r25529: Reformatting.
[tprouty/samba.git] / source / torture / rpc / winreg.c
index b0c2605bae60ac4b4adb8466565b3ed1e6c7af96..cded33d0593dab545978f854f12c972b4793efa2 100644 (file)
@@ -3,11 +3,11 @@
    test suite for winreg rpc operations
 
    Copyright (C) Tim Potter 2003
-   Copyright (C) Jelmer Vernooij 2004
+   Copyright (C) Jelmer Vernooij 2004-2007
    
    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_winreg.h"
+#include "torture/torture.h"
+#include "librpc/gen_ndr/ndr_winreg_c.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/security/security.h"
+#include "torture/rpc/rpc.h"
 
 #define TEST_KEY_BASE "smbtorture test"
 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
+#define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
+#define TEST_SUBKEY TEST_KEY3 "\\subkey"
 
-static void init_initshutdown_String(TALLOC_CTX *mem_ctx, struct initshutdown_String *name, const char *s)
+static void init_initshutdown_String(TALLOC_CTX *mem_ctx,
+                                     struct initshutdown_String *name,
+                                     const char *s)
 {
        name->name = talloc(mem_ctx, struct initshutdown_String_sub);
        name->name->name = s;
@@ -45,38 +52,30 @@ static void init_winreg_String(struct winreg_String *name, const char *s)
        }
 }
 
-static BOOL test_GetVersion(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static bool test_GetVersion(struct dcerpc_pipe *p,
+                           struct torture_context *tctx,
                            struct policy_handle *handle)
 {
-       NTSTATUS status;
        struct winreg_GetVersion r;
+       uint32_t v;
 
-       printf("\ntesting GetVersion\n");
-
+       ZERO_STRUCT(r);
        r.in.handle = handle;
+       r.out.version = &v;
 
-       status = dcerpc_winreg_GetVersion(p, mem_ctx, &r);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("GetVersion failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion(p, tctx, &r),
+                                                          "GetVersion failed");
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("GetVersion failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
 
-       return True;
+       return true;
 }
 
-static BOOL test_NotifyChangeKeyValue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                                                                         struct policy_handle *handle)
+static bool test_NotifyChangeKeyValue(struct dcerpc_pipe *p,
+                                     struct torture_context *tctx,
+                                     struct policy_handle *handle)
 {
        struct winreg_NotifyChangeKeyValue r;
-       NTSTATUS status;
-
-       printf("\ntesting NotifyChangeKeyValue\n");
 
        r.in.handle = handle;
        r.in.watch_subtree = 1;
@@ -85,72 +84,60 @@ static BOOL test_NotifyChangeKeyValue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx
        init_winreg_String(&r.in.string1, NULL);
        init_winreg_String(&r.in.string2, NULL);
 
-       status = dcerpc_winreg_NotifyChangeKeyValue(p, mem_ctx, &r);
-       
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("NotifyChangeKeyValue failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx,
+                                  dcerpc_winreg_NotifyChangeKeyValue(p, tctx, &r),
+                                  "NotifyChangeKeyValue failed");
 
        if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("NotifyChangeKeyValue failed - %s - not considering\n", win_errstr(r.out.result));
-               return True;
+               torture_comment(tctx,
+                               "NotifyChangeKeyValue failed - %s - not considering\n", win_errstr(r.out.result));
+               return true;
        }
 
-       return True;
+       return true;
 }
 
-static BOOL test_CreateKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
-                         struct policy_handle *handle, const char *name, 
+static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx,
+                          struct policy_handle *handle, const char *name,
                           const char *class)
 {
        struct winreg_CreateKey r;
        struct policy_handle newhandle;
-       NTSTATUS status;
-       uint32_t action_taken = 0;
-
-       printf("\ntesting CreateKey\n");
+       enum winreg_CreateAction action_taken = 0;
 
        r.in.handle = handle;
        r.out.new_handle = &newhandle;
-       init_winreg_String(&r.in.name, name);   
-       init_winreg_String(&r.in.class, class);
+       init_winreg_String(&r.in.name, name);
+       init_winreg_String(&r.in.keyclass, class);
        r.in.options = 0x0;
-       r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED;
+       r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        r.in.action_taken = r.out.action_taken = &action_taken;
        r.in.secdesc = NULL;
 
-       status = dcerpc_winreg_CreateKey(p, mem_ctx, &r);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("CreateKey failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
+               "CreateKey failed");
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("CreateKey failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx,  r.out.result, "CreateKey failed");
 
-       return True;
+       return true;
 }
 
 
 /*
   createkey testing with a SD
 */
-static BOOL test_CreateKey_sd(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
-                             struct policy_handle *handle, const char *name, 
+static bool test_CreateKey_sd(struct dcerpc_pipe *p,
+                             struct torture_context *tctx,
+                             struct policy_handle *handle, const char *name,
                              const char *class, struct policy_handle *newhandle)
 {
        struct winreg_CreateKey r;
-       NTSTATUS status;
-       uint32_t action_taken = 0;
+       enum winreg_CreateAction action_taken = 0;
        struct security_descriptor *sd;
        DATA_BLOB sdblob;
        struct winreg_SecBuf secbuf;
 
-       sd = security_descriptor_create(mem_ctx,
+       sd = security_descriptor_create(tctx,
                                        NULL, NULL,
                                        SID_NT_AUTHENTICATED_USERS,
                                        SEC_ACE_TYPE_ACCESS_ALLOWED,
@@ -158,12 +145,10 @@ static BOOL test_CreateKey_sd(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                        SEC_ACE_FLAG_OBJECT_INHERIT,
                                        NULL);
 
-       status = ndr_push_struct_blob(&sdblob, mem_ctx, sd, 
-                                     (ndr_push_flags_fn_t)ndr_push_security_descriptor);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("Failed to push security_descriptor ?!\n");
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx,
+               ndr_push_struct_blob(&sdblob, tctx, sd,
+                                    (ndr_push_flags_fn_t)ndr_push_security_descriptor),
+                                    "Failed to push security_descriptor ?!\n");
 
        secbuf.sd.data = sdblob.data;
        secbuf.sd.len = sdblob.length;
@@ -171,159 +156,109 @@ static BOOL test_CreateKey_sd(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        secbuf.length = sdblob.length-10;
        secbuf.inherit = 0;
 
-       printf("\ntesting CreateKey with sd\n");
-
        r.in.handle = handle;
        r.out.new_handle = newhandle;
-       init_winreg_String(&r.in.name, name);   
-       init_winreg_String(&r.in.class, class);
+       init_winreg_String(&r.in.name, name);
+       init_winreg_String(&r.in.keyclass, class);
        r.in.options = 0x0;
-       r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED;
+       r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        r.in.action_taken = r.out.action_taken = &action_taken;
        r.in.secdesc = &secbuf;
 
-       status = dcerpc_winreg_CreateKey(p, mem_ctx, &r);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("CreateKey with sd failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
+               "CreateKey with sd failed");
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("CreateKey with sd failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
 
-       return True;
+       return true;
 }
 
-static BOOL test_GetKeySecurity(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                         struct policy_handle *handle)
+static bool test_GetKeySecurity(struct dcerpc_pipe *p,
+                               struct torture_context *tctx,
+                               struct policy_handle *handle)
 {
-       NTSTATUS status;
        struct winreg_GetKeySecurity r;
        struct security_descriptor sd;
        DATA_BLOB sdblob;
 
-       printf("\ntesting GetKeySecurity\n");
-
        ZERO_STRUCT(r);
 
        r.in.handle = handle;
-       r.in.sd = r.out.sd = talloc_zero(mem_ctx, struct KeySecurityData);
+       r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
        r.in.sd->size = 0x1000;
        r.in.sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
 
-       status = dcerpc_winreg_GetKeySecurity(p, mem_ctx, &r);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("GetKeySecurity failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetKeySecurity(p, tctx, &r),
+               "GetKeySecurity failed");
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("GetKeySecurity failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "GetKeySecurity failed");
 
        sdblob.data = r.out.sd->data;
        sdblob.length = r.out.sd->len;
 
-       status = ndr_pull_struct_blob(&sdblob, mem_ctx, &sd, 
-                                     (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("pull_security_descriptor failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx,
+               ndr_pull_struct_blob(&sdblob, tctx, &sd,
+                                    (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
+                                    "pull_security_descriptor failed");
+
        if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
                NDR_PRINT_DEBUG(security_descriptor, &sd);
        }
 
-       return True;
+       return true;
 }
 
-static BOOL test_CloseKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx,
                          struct policy_handle *handle)
 {
-       NTSTATUS status;
        struct winreg_CloseKey r;
 
-       printf("\ntesting CloseKey\n");
-
        r.in.handle = r.out.handle = handle;
 
-       status = dcerpc_winreg_CloseKey(p, mem_ctx, &r);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("CloseKey failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey(p, tctx, &r),
+                                                               "CloseKey failed");
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("CloseKey failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
 
-       return True;
+       return true;
 }
 
-static BOOL test_FlushKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx,
                          struct policy_handle *handle)
 {
-       NTSTATUS status;
        struct winreg_FlushKey r;
 
-       printf("\ntesting FlushKey\n");
-
        r.in.handle = handle;
 
-       status = dcerpc_winreg_FlushKey(p, mem_ctx, &r);
+       torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey(p, tctx, &r),
+                                  "FlushKey failed");
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("FlushKey failed - %s\n", nt_errstr(status));
-               return False;
-       }
-
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("FlushKey failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
 
-       return True;
+       return true;
 }
 
-static BOOL test_OpenKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static bool test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
                         struct policy_handle *hive_handle,
                         const char *keyname, struct policy_handle *key_handle)
 {
-       NTSTATUS status;
        struct winreg_OpenKey r;
 
-       printf("\ntesting OpenKey\n");
-
-       r.in.handle = hive_handle;
+       r.in.parent_handle = hive_handle;
        init_winreg_String(&r.in.keyname, keyname);
        r.in.unknown = 0x00000000;
        r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        r.out.handle = key_handle;
 
-       status = dcerpc_winreg_OpenKey(p, mem_ctx, &r);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("OpenKey failed - %s\n", nt_errstr(status));
-               return False;
-       }
-
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("OpenKey failed - %s\n", win_errstr(r.out.result));
+       torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey(p, tctx, &r),
+                                  "OpenKey failed");
 
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "OpenKey failed");
 
-       return True;
+       return true;
 }
 
-static BOOL test_Cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx,
                         struct policy_handle *handle, const char *key)
 {
        struct winreg_DeleteKey r;
@@ -331,68 +266,88 @@ static BOOL test_Cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        r.in.handle = handle;
 
        init_winreg_String(&r.in.key, key);
-       dcerpc_winreg_DeleteKey(p, mem_ctx, &r);
+       dcerpc_winreg_DeleteKey(p, tctx, &r);
 
-       return True;
+       return true;
 }
 
 
-static BOOL test_DeleteKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
                           struct policy_handle *handle, const char *key)
 {
        NTSTATUS status;
        struct winreg_DeleteKey r;
 
-       printf("\ntesting DeleteKey\n");
-
        r.in.handle = handle;
-       init_winreg_String(&r.in.key, key);     
+       init_winreg_String(&r.in.key, key);
 
-       status = dcerpc_winreg_DeleteKey(p, mem_ctx, &r);
+       status = dcerpc_winreg_DeleteKey(p, tctx, &r);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("DeleteKey failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
+       torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("DeleteKey failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       return true;
+}
+
+/* DeleteKey on a key with subkey(s) should
+ * return WERR_ACCESS_DENIED. */
+static bool test_DeleteKeyWithSubkey(struct dcerpc_pipe *p,
+                                    struct torture_context *tctx,
+                                    struct policy_handle *handle, const char *key)
+{
+       struct winreg_DeleteKey r;
+
+       r.in.handle = handle;
+       init_winreg_String(&r.in.key, key);
 
-       return True;
+       torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey(p, tctx, &r),
+                                                                "DeleteKeyWithSubkey failed");
+
+       torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
+                                 "DeleteKeyWithSubkey failed");
+
+       return true;
 }
 
-static BOOL test_QueryInfoKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+static bool test_QueryInfoKey(struct dcerpc_pipe *p,
+                             struct torture_context *tctx,
                              struct policy_handle *handle, char *class)
 {
-       NTSTATUS status;
        struct winreg_QueryInfoKey r;
+       uint32_t num_subkeys, max_subkeylen, max_subkeysize,
+               num_values, max_valnamelen, max_valbufsize,
+               secdescsize;
+       NTTIME last_changed_time;
 
-       printf("\ntesting QueryInfoKey\n");
-
+       ZERO_STRUCT(r);
        r.in.handle = handle;
-       init_winreg_String(&r.in.class, class);
-       
-       status = dcerpc_winreg_QueryInfoKey(p, mem_ctx, &r);
+       r.out.num_subkeys = &num_subkeys;
+       r.out.max_subkeylen = &max_subkeylen;
+       r.out.max_subkeysize = &max_subkeysize;
+       r.out.num_values = &num_values;
+       r.out.max_valnamelen = &max_valnamelen;
+       r.out.max_valbufsize = &max_valbufsize;
+       r.out.secdescsize = &secdescsize;
+       r.out.last_changed_time = &last_changed_time;
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("QueryInfoKey failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       r.out.classname = talloc(tctx, struct winreg_String);
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("QueryInfoKey failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       r.in.classname = talloc(tctx, struct winreg_String);
+       init_winreg_String(r.in.classname, class);
+
+       torture_assert_ntstatus_ok(tctx,
+               dcerpc_winreg_QueryInfoKey(p, tctx, &r),
+               "QueryInfoKey failed");
+
+       torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
 
-       return True;
+       return true;
 }
 
-static BOOL test_key(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
                     struct policy_handle *handle, int depth);
 
-static BOOL test_EnumKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
                         struct policy_handle *handle, int depth)
 {
        struct winreg_EnumKey r;
@@ -400,32 +355,33 @@ static BOOL test_EnumKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        NTTIME t = 0;
 
-       printf("Testing EnumKey\n\n");
-
        class.name   = "";
+       class.size   = 1024;
 
        r.in.handle = handle;
        r.in.enum_index = 0;
        r.in.name = &name;
-       r.in.class = &class;
+       r.in.keyclass = &class;
        r.out.name = &name;
        r.in.last_changed_time = &t;
 
        do {
                name.name   = NULL;
+               name.size   = 1024;
 
-               status = dcerpc_winreg_EnumKey(p, mem_ctx, &r);
+               status = dcerpc_winreg_EnumKey(p, tctx, &r);
 
                if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
                        struct policy_handle key_handle;
 
-                       printf("EnumKey: %d: %s\n", r.in.enum_index, r.out.name->name);
+                       torture_comment(tctx, "EnumKey: %d: %s\n", r.in.enum_index, 
+                                                       r.out.name->name);
 
                        if (!test_OpenKey(
-                                   p, mem_ctx, handle, r.out.name->name,
+                                   p, tctx, handle, r.out.name->name,
                                    &key_handle)) {
                        } else {
-                               test_key(p, mem_ctx, &key_handle, depth + 1);
+                               test_key(p, tctx, &key_handle, depth + 1);
                        }
                }
 
@@ -433,106 +389,96 @@ static BOOL test_EnumKey(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("EnumKey failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
 
-       if (!W_ERROR_IS_OK(r.out.result) && !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
-               printf("EnumKey failed - %s\n", win_errstr(r.out.result));
-               return False;
+       if (!W_ERROR_IS_OK(r.out.result) &&
+               !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
+               torture_fail(tctx, "EnumKey failed");
        }
 
-
-
-       return True;
+       return true;
 }
 
-static BOOL test_QueryMultipleValues(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, const char *valuename)
+static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
+                                    struct torture_context *tctx,
+                                    struct policy_handle *handle,
+                                    const char *valuename)
 {
        struct winreg_QueryMultipleValues r;
        NTSTATUS status;
        uint32_t bufsize=0;
 
-       printf("Testing QueryMultipleValues\n");
-
        r.in.key_handle = handle;
-       r.in.values = r.out.values = talloc_array(mem_ctx, struct QueryMultipleValue, 1);
-       r.in.values[0].name = talloc(mem_ctx, struct winreg_String);
+       r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
+       r.in.values[0].name = talloc(tctx, struct winreg_String);
        r.in.values[0].name->name = valuename;
        r.in.values[0].offset = 0;
        r.in.values[0].length = 0;
        r.in.values[0].type = 0;
 
        r.in.num_values = 1;
-       r.in.buffer_size = r.out.buffer_size = talloc(mem_ctx, uint32_t);
+       r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
        *r.in.buffer_size = bufsize;
-       do { 
+       do {
                *r.in.buffer_size = bufsize;
-               r.in.buffer = r.out.buffer = talloc_zero_array(mem_ctx, uint8_t, 
+               r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
                                                               *r.in.buffer_size);
 
-               status = dcerpc_winreg_QueryMultipleValues(p, mem_ctx, &r);
-       
-               if(NT_STATUS_IS_ERR(status)) {
-                       printf("QueryMultipleValues failed - %s\n", nt_errstr(status));
-                       return False;
-               }
+               status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
+
+               if(NT_STATUS_IS_ERR(status))
+                       torture_fail(tctx, "QueryMultipleValues failed");
+
                talloc_free(r.in.buffer);
                bufsize += 0x20;
        } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("QueryMultipleValues failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
 
-       return True;
+       return true;
 }
 
-static BOOL test_QueryValue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, const char *valuename)
+static bool test_QueryValue(struct dcerpc_pipe *p,
+                           struct torture_context *tctx,
+                           struct policy_handle *handle,
+                           const char *valuename)
 {
        struct winreg_QueryValue r;
        NTSTATUS status;
-       uint32_t zero = 0;
+       enum winreg_Type zero_type = 0;
        uint32_t offered = 0xfff;
-
-       printf("Testing QueryValue\n");
+       uint32_t zero = 0;
 
        r.in.handle = handle;
        r.in.data = NULL;
        r.in.value_name.name = valuename;
-       r.in.type = &zero;
+       r.in.type = &zero_type;
        r.in.size = &offered;
        r.in.length = &zero;
 
-       status = dcerpc_winreg_QueryValue(p, mem_ctx, &r);
-       if(NT_STATUS_IS_ERR(status)) {
-               printf("QueryValue failed - %s\n", nt_errstr(status));
-               return False;
+       status = dcerpc_winreg_QueryValue(p, tctx, &r);
+       if (NT_STATUS_IS_ERR(status)) {
+               torture_fail(tctx, "QueryValue failed");
        }
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("QueryValue failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
 
-       return True;
+       return true;
 }
 
-static BOOL test_EnumValue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                          struct policy_handle *handle, int max_valnamelen, int max_valbufsize)
+static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
+                          struct policy_handle *handle, int max_valnamelen,
+                          int max_valbufsize)
 {
        struct winreg_EnumValue r;
-       uint32_t type = 0;
+       enum winreg_Type type = 0;
        uint32_t size = max_valbufsize, zero = 0;
-       BOOL ret = True;
+       bool ret = true;
        uint8_t buf8;
        struct winreg_StringBuf name;
 
-       printf("testing EnumValue\n");
-
        name.name   = "";
+       name.size   = 1024;
 
        r.in.handle = handle;
        r.in.enum_index = 0;
@@ -542,252 +488,250 @@ static BOOL test_EnumValue(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        r.in.value = &buf8;
        r.in.length = &zero;
        r.in.size = &size;
-       
+
        do {
-               NTSTATUS status = dcerpc_winreg_EnumValue(p, mem_ctx, &r);
-               if(NT_STATUS_IS_ERR(status)) {
-                       printf("EnumValue failed - %s\n", nt_errstr(status));
-                       return False;
-               }
+               torture_assert_ntstatus_ok(tctx, dcerpc_winreg_EnumValue(p, tctx, &r),
+                                                                        "EnumValue failed");
 
                if (W_ERROR_IS_OK(r.out.result)) {
-                       ret &= test_QueryValue(p, mem_ctx, handle, r.out.name->name);
-                       ret &= test_QueryMultipleValues(p, mem_ctx, handle, r.out.name->name);
+                       ret &= test_QueryValue(p, tctx, handle, r.out.name->name);
+                       ret &= test_QueryMultipleValues(p, tctx, handle, r.out.name->name);
                }
 
                r.in.enum_index++;
        } while (W_ERROR_IS_OK(r.out.result));
 
-       if(!W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
-               printf("EnumValue failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
+               "EnumValue failed");
 
        return ret;
 }
 
-static BOOL test_InitiateSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
-                       const char *msg, uint32_t timeout)
+static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
+                                    struct torture_context *tctx)
 {
-       struct winreg_InitiateSystemShutdown r;
-       NTSTATUS status;
-       uint16_t hostname = 0x0;
-       
-       r.in.hostname = &hostname;
-       r.in.message = talloc(mem_ctx, struct initshutdown_String);
-       init_initshutdown_String(mem_ctx, r.in.message, msg);
-       r.in.force_apps = 1;
-       r.in.timeout = timeout;
-       r.in.reboot = 1;
+       struct winreg_AbortSystemShutdown r;
+       uint16_t server = 0x0;
 
-       status = dcerpc_winreg_InitiateSystemShutdown(p, mem_ctx, &r);
+       r.in.server = &server;
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("InitiateSystemShutdown failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx,
+                                  dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
+                                  "AbortSystemShutdown failed");
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("InitiateSystemShutdown failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "AbortSystemShutdown failed");
 
-       return True;
+       return true;
 }
 
-static BOOL test_InitiateSystemShutdownEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
-                       const char *msg, uint32_t timeout)
+static bool test_InitiateSystemShutdown(struct torture_context *tctx,
+                                       struct dcerpc_pipe *p)
 {
-       struct winreg_InitiateSystemShutdownEx r;
-       NTSTATUS status;
+       struct winreg_InitiateSystemShutdown r;
        uint16_t hostname = 0x0;
-       
+
        r.in.hostname = &hostname;
-       r.in.message = talloc(mem_ctx, struct initshutdown_String);
-       init_initshutdown_String(mem_ctx, r.in.message, msg);
+       r.in.message = talloc(tctx, struct initshutdown_String);
+       init_initshutdown_String(tctx, r.in.message, "spottyfood");
        r.in.force_apps = 1;
-       r.in.timeout = timeout;
+       r.in.timeout = 30;
        r.in.reboot = 1;
-       r.in.reason = 0;
 
-       status = dcerpc_winreg_InitiateSystemShutdownEx(p, mem_ctx, &r);
+       torture_assert_ntstatus_ok(tctx,
+                                  dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
+                                  "InitiateSystemShutdown failed");
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("InitiateSystemShutdownEx failed - %s\n", nt_errstr(status));
-               return False;
-       }
-
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("InitiateSystemShutdownEx failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result, "InitiateSystemShutdown failed");
 
-       return True;
+       return test_AbortSystemShutdown(p, tctx);
 }
 
-static BOOL test_AbortSystemShutdown(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+
+static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
+                                         struct dcerpc_pipe *p)
 {
-       struct winreg_AbortSystemShutdown r;
-       NTSTATUS status;
-       uint16_t server = 0x0;
+       struct winreg_InitiateSystemShutdownEx r;
+       uint16_t hostname = 0x0;
 
-       r.in.server = &server;
-       
-       status = dcerpc_winreg_AbortSystemShutdown(p, mem_ctx, &r);
+       r.in.hostname = &hostname;
+       r.in.message = talloc(tctx, struct initshutdown_String);
+       init_initshutdown_String(tctx, r.in.message, "spottyfood");
+       r.in.force_apps = 1;
+       r.in.timeout = 30;
+       r.in.reboot = 1;
+       r.in.reason = 0;
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("AbortSystemShutdown failed - %s\n", nt_errstr(status));
-               return False;
-       }
+       torture_assert_ntstatus_ok(tctx,
+               dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
+               "InitiateSystemShutdownEx failed");
 
-       if (!W_ERROR_IS_OK(r.out.result)) {
-               printf("AbortSystemShutdown failed - %s\n", win_errstr(r.out.result));
-               return False;
-       }
+       torture_assert_werr_ok(tctx, r.out.result,
+                              "InitiateSystemShutdownEx failed");
 
-       return True;
+       return test_AbortSystemShutdown(p, tctx);
 }
-
 #define MAX_DEPTH 2            /* Only go this far down the tree */
 
-static BOOL test_key(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
                     struct policy_handle *handle, int depth)
 {
        if (depth == MAX_DEPTH)
-               return True;
+               return true;
 
-       if (!test_QueryInfoKey(p, mem_ctx, handle, NULL)) {
+       if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
        }
 
-
-       if (!test_NotifyChangeKeyValue(p, mem_ctx, handle)) {
-       }
-       
-       if (!test_GetKeySecurity(p, mem_ctx, handle)) {
+       if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
        }
 
-       if (!test_EnumKey(p, mem_ctx, handle, depth)) {
+       if (!test_GetKeySecurity(p, tctx, handle)) {
        }
 
-       if (!test_EnumValue(p, mem_ctx, handle, 0xFF, 0xFFFF)) {
+       if (!test_EnumKey(p, tctx, handle, depth)) {
        }
 
+       if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
+       }
 
-       test_CloseKey(p, mem_ctx, handle);
+       test_CloseKey(p, tctx, handle);
 
-       return True;
+       return true;
 }
 
 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
 
-static BOOL test_Open(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                     const char *name, winreg_open_fn open_fn)
+static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
+                     void *userdata)
 {
        struct policy_handle handle, newhandle;
-       BOOL ret = True, created = False, deleted = False;
+       bool ret = true, created = false, created2 = false, deleted = false;
+       bool created3 = false, created_subkey = false;
        struct winreg_OpenHKLM r;
-       NTSTATUS status;
 
-       printf("Testing %s\n", name);
+       winreg_open_fn open_fn = userdata;
 
        r.in.system_name = 0;
-       r.in.access_required = SEC_FLAG_MAXIMUM_ALLOWED;
+       r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        r.out.handle = &handle;
-       
-       status = open_fn(p, mem_ctx, &r);
-       if (!NT_STATUS_IS_OK(status)) {
-               return False;
-       }
 
-       test_Cleanup(p, mem_ctx, &handle, TEST_KEY1);
-       test_Cleanup(p, mem_ctx, &handle, TEST_KEY2);
-       test_Cleanup(p, mem_ctx, &handle, TEST_KEY_BASE);
+       torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
+                                  "open");
+
+       test_Cleanup(p, tctx, &handle, TEST_KEY1);
+       test_Cleanup(p, tctx, &handle, TEST_KEY2);
+       test_Cleanup(p, tctx, &handle, TEST_SUBKEY);
+       test_Cleanup(p, tctx, &handle, TEST_KEY3);
+       test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
 
-       if (!test_CreateKey(p, mem_ctx, &handle, TEST_KEY1, NULL)) {
-               printf("CreateKey failed - not considering a failure\n");
+       if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
+               torture_comment(tctx, "CreateKey failed - not considering a failure\n");
        } else {
-               created = True;
+               created = true;
        }
 
-       if (created && !test_FlushKey(p, mem_ctx, &handle)) {
-               printf("FlushKey failed\n");
-               ret = False;
+       if (created && !test_FlushKey(p, tctx, &handle)) {
+               torture_comment(tctx, "FlushKey failed\n");
+               ret = false;
        }
 
-       if (created && !test_OpenKey(p, mem_ctx, &handle, TEST_KEY1, &newhandle)) {
-               printf("CreateKey failed (OpenKey after Create didn't work)\n");
-               ret = False;
-       }
+       if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
+               torture_fail(tctx,
+                            "CreateKey failed (OpenKey after Create didn't work)\n");
 
-       if (created && !test_DeleteKey(p, mem_ctx, &handle, TEST_KEY1)) {
-               printf("DeleteKey failed\n");
-               ret = False;
+       if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
+               torture_comment(tctx, "DeleteKey failed\n");
+               ret = false;
        } else {
-               deleted = True;
+               deleted = true;
        }
 
-       if (created && !test_FlushKey(p, mem_ctx, &handle)) {
-               printf("FlushKey failed\n");
-               ret = False;
+       if (created && !test_FlushKey(p, tctx, &handle)) {
+               torture_comment(tctx, "FlushKey failed\n");
+               ret = false;
        }
 
-       if (created && deleted && 
-           test_OpenKey(p, mem_ctx, &handle, TEST_KEY1, &newhandle)) {
-               printf("DeleteKey failed (OpenKey after Delete didn't work)\n");
-               ret = False;
+       if (created && deleted &&
+           test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle)) {
+               torture_comment(tctx,
+                               "DeleteKey failed (OpenKey after Delete worked)\n");
+               ret = false;
        }
 
-       if (!test_GetVersion(p, mem_ctx, &handle)) {
-               printf("GetVersion failed\n");
-               ret = False;
+       if (!test_GetVersion(p, tctx, &handle)) {
+               torture_comment(tctx, "GetVersion failed\n");
+               ret = false;
        }
 
-       if (created && !test_CreateKey_sd(p, mem_ctx, &handle, TEST_KEY2, 
-                                         NULL, &newhandle)) {
-               printf("CreateKey failed - not considering a failure\n");
-               created = False;
-       } else {
-               created = True;
+       if (created && test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
+                                        NULL, &newhandle)) {
+               created2 = true;
        }
 
-       if (created && !test_GetKeySecurity(p, mem_ctx, &newhandle)) {
+       if (created2 && !test_GetKeySecurity(p, tctx, &newhandle)) {
                printf("GetKeySecurity failed\n");
-               ret = False;
+               ret = false;
        }
 
-       if (created && !test_CloseKey(p, mem_ctx, &newhandle)) {
+       if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
                printf("CloseKey failed\n");
-               ret = False;
+               ret = false;
        }
 
-       if (created && !test_DeleteKey(p, mem_ctx, &handle, TEST_KEY2)) {
+       if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
                printf("DeleteKey failed\n");
-               ret = False;
+               ret = false;
        }
 
-       /* The HKCR hive has a very large fanout */
+       if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
+               created3 = true;
+       }
+
+       if (created3 &&
+           test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL))
+       {
+               created_subkey = true;
+       }
+
+       if (created_subkey &&
+           !test_DeleteKeyWithSubkey(p, tctx, &handle, TEST_KEY3))
+       {
+               printf("DeleteKeyWithSubkey failed "
+                      "(DeleteKey didn't return ACCESS_DENIED)\n");
+               ret = false;
+       }
+
+       if (created_subkey &&
+           !test_DeleteKey(p, tctx, &handle, TEST_SUBKEY))
+       {
+               printf("DeleteKey failed\n");
+               ret = false;
+       }
 
+       if (created3 &&
+           !test_DeleteKey(p, tctx, &handle, TEST_KEY3))
+       {
+               printf("DeleteKey failed\n");
+               ret = false;
+       }
+
+       /* The HKCR hive has a very large fanout */
        if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
-               if(!test_key(p, mem_ctx, &handle, MAX_DEPTH - 1)) {
-                       ret = False;
+               if(!test_key(p, tctx, &handle, MAX_DEPTH - 1)) {
+                       ret = false;
                }
        }
 
-       if(!test_key(p, mem_ctx, &handle, 0)) {
-               ret = False;
+       if(!test_key(p, tctx, &handle, 0)) {
+               ret = false;
        }
 
-       test_Cleanup(p, mem_ctx, &handle, TEST_KEY_BASE);
+       test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
 
        return ret;
 }
 
-BOOL torture_rpc_winreg(void)
+struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
 {
-        NTSTATUS status;
-       struct dcerpc_pipe *p;
-       TALLOC_CTX *mem_ctx;
-       BOOL ret = True;
        struct {
                const char *name;
                winreg_open_fn fn;
@@ -796,34 +740,25 @@ BOOL torture_rpc_winreg(void)
                        {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR },
                        {"OpenHKCU", (winreg_open_fn)dcerpc_winreg_OpenHKCU }};
        int i;
-       mem_ctx = talloc_init("torture_rpc_winreg");
+       struct torture_rpc_tcase *tcase;
+       struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
+       struct torture_test *test;
 
-       status = torture_rpc_connection(mem_ctx, 
-                                       &p, 
-                                       DCERPC_WINREG_NAME, 
-                                       DCERPC_WINREG_UUID, 
-                                       DCERPC_WINREG_VERSION);
+       tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
+                                                 &ndr_table_winreg);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(mem_ctx);
-               return False;
-       }
+       test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
+                                         test_InitiateSystemShutdown);
+       test->dangerous = true;
 
-       if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
-               printf("winreg_InitiateShutdown disabled - enable dangerous tests to use\n");
-       } else {
-               ret &= test_InitiateSystemShutdown(p, mem_ctx, "spottyfood", 30);
-               ret &= test_AbortSystemShutdown(p, mem_ctx);
-               ret &= test_InitiateSystemShutdownEx(p, mem_ctx, "spottyfood", 30);
-               ret &= test_AbortSystemShutdown(p, mem_ctx);
-       }
+       test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
+                                         test_InitiateSystemShutdownEx);
+       test->dangerous = true;
 
        for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
-               if (!test_Open(p, mem_ctx, open_fns[i].name, open_fns[i].fn))
-                       ret = False;
+               torture_rpc_tcase_add_test_ex(tcase, open_fns[i].name,
+                                             test_Open, open_fns[i].fn);
        }
 
-       talloc_free(mem_ctx);
-
-       return ret;
+       return suite;
 }