diff options
-rw-r--r-- | source4/lib/registry/dir.c | 60 | ||||
-rw-r--r-- | source4/lib/registry/ldb.c | 143 | ||||
-rw-r--r-- | source4/lib/registry/regf.c | 53 | ||||
-rw-r--r-- | source4/lib/registry/tests/hive.c | 37 | ||||
-rw-r--r-- | source4/samba4-knownfail | 2 | ||||
-rw-r--r-- | source4/torture/rpc/winreg.c | 230 |
6 files changed, 383 insertions, 142 deletions
diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 27cae8c490..dc3717e886 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -55,18 +55,66 @@ static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, return WERR_GENERAL_FAILURE; } +static WERROR reg_dir_delete_recursive(const char *name) +{ + DIR *d; + struct dirent *e; + WERROR werr; + + d = opendir(name); + if (d == NULL) { + DEBUG(3,("Unable to open '%s': %s\n", name, + strerror(errno))); + return WERR_BADFILE; + } + + while((e = readdir(d))) { + char *path; + struct stat stbuf; + + if (ISDOT(e->d_name) || ISDOTDOT(e->d_name)) + continue; + + path = talloc_asprintf(name, "%s/%s", name, e->d_name); + if (!path) + return WERR_NOMEM; + + stat(path, &stbuf); + + if (!S_ISDIR(stbuf.st_mode)) { + if (unlink(path) < 0) { + talloc_free(path); + closedir(d); + return WERR_GENERAL_FAILURE; + } + } else { + werr = reg_dir_delete_recursive(path); + if (!W_ERROR_IS_OK(werr)) { + talloc_free(path); + closedir(d); + return werr; + } + } + + talloc_free(path); + } + closedir(d); + + if (rmdir(name) == 0) + return WERR_OK; + else if (errno == ENOENT) + return WERR_BADFILE; + else + return WERR_GENERAL_FAILURE; +} + static WERROR reg_dir_del_key(const struct hive_key *k, const char *name) { struct dir_key *dk = talloc_get_type(k, struct dir_key); char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name); WERROR ret; - if (rmdir(child) == 0) - ret = WERR_OK; - else if (errno == ENOENT) - ret = WERR_BADFILE; - else - ret = WERR_GENERAL_FAILURE; + ret = reg_dir_delete_recursive(child); talloc_free(child); diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index dfd368ea80..a764ca6235 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -442,33 +442,6 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, return WERR_OK; } -static WERROR ldb_del_key(const struct hive_key *key, const char *name) -{ - int ret; - struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); - struct ldb_dn *ldap_path; - TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); - - ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); - - ret = ldb_delete(parentkd->ldb, ldap_path); - - talloc_free(mem_ctx); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - return WERR_BADFILE; - } else if (ret != LDB_SUCCESS) { - DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb))); - return WERR_FOOBAR; - } - - /* reset cache */ - talloc_free(parentkd->subkeys); - parentkd->subkeys = NULL; - - return WERR_OK; -} - static WERROR ldb_del_value (struct hive_key *key, const char *child) { int ret; @@ -501,6 +474,122 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) return WERR_OK; } +static WERROR ldb_del_key(const struct hive_key *key, const char *name) +{ + int i, ret; + struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); + struct ldb_dn *ldap_path; + TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key"); + struct ldb_context *c = parentkd->ldb; + struct ldb_result *res_keys; + struct ldb_result *res_vals; + WERROR werr; + struct hive_key *hk; + + /* Verify key exists by opening it */ + werr = ldb_open_key(mem_ctx, key, name, &hk); + if (!W_ERROR_IS_OK(werr)) { + talloc_free(mem_ctx); + return werr; + } + + ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL); + if (!ldap_path) { + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Search for subkeys */ + ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, + "(key=*)", NULL, &res_keys); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting subkeys for '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Search for values */ + ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL, + "(value=*)", NULL, &res_vals); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Error getting values for '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Start an explicit transaction */ + ret = ldb_transaction_start(c); + + if (ret != LDB_SUCCESS) { + DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c))); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + if (res_keys->count || res_vals->count) + { + /* Delete any subkeys */ + for (i = 0; i < res_keys->count; i++) + { + werr = ldb_del_key(hk, ldb_msg_find_attr_as_string( + res_keys->msgs[i], + "key", NULL)); + if (!W_ERROR_IS_OK(werr)) { + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return werr; + } + } + + /* Delete any values */ + for (i = 0; i < res_vals->count; i++) + { + werr = ldb_del_value(hk, ldb_msg_find_attr_as_string( + res_vals->msgs[i], + "value", NULL)); + if (!W_ERROR_IS_OK(werr)) { + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return werr; + } + } + } + + /* Delete the key itself */ + ret = ldb_delete(c, ldap_path); + + if (ret != LDB_SUCCESS) + { + DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c))); + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + /* Commit the transaction */ + ret = ldb_transaction_commit(c); + + if (ret != LDB_SUCCESS) + { + DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c))); + ret = ldb_transaction_cancel(c); + talloc_free(mem_ctx); + return WERR_FOOBAR; + } + + talloc_free(mem_ctx); + + /* reset cache */ + talloc_free(parentkd->subkeys); + parentkd->subkeys = NULL; + + return WERR_OK; +} + static WERROR ldb_set_value(struct hive_key *parent, const char *name, uint32_t type, const DATA_BLOB data) diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index cf3e564c0e..a192f3be4d 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -1618,10 +1618,55 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) return WERR_BADFILE; } - if (key->nk->subkeys_offset != -1 || - key->nk->values_offset != -1) { - DEBUG(0, ("Key '%s' is not empty.\n", name)); - return WERR_FILE_EXISTS; + if (key->nk->subkeys_offset != -1) { + char *sk_name; + struct hive_key *sk = (struct hive_key *)key; + int i = key->nk->num_subkeys; + while (i--) { + /* Get subkey information. */ + error = regf_get_subkey_by_index(parent_nk, sk, 0, + (const char **)&sk_name, + NULL, NULL); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't retrieve subkey by index.\n")); + return error; + } + + /* Delete subkey. */ + error = regf_del_key(sk, sk_name); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't delete key '%s'.\n", sk_name)); + return error; + } + + talloc_free(sk_name); + } + } + + if (key->nk->values_offset != -1) { + char *val_name; + struct hive_key *sk = (struct hive_key *)key; + DATA_BLOB data; + int i = key->nk->num_values; + while (i--) { + /* Get value information. */ + error = regf_get_value(parent_nk, sk, 0, + (const char **)&val_name, + NULL, &data); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't retrieve value by index.\n")); + return error; + } + + /* Delete value. */ + error = regf_del_value(sk, val_name); + if (!W_ERROR_IS_OK(error)) { + DEBUG(0, ("Can't delete value '%s'.\n", val_name)); + return error; + } + + talloc_free(val_name); + } } /* Delete it from the subkey list. */ diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index 1dcb464d80..1e56f125c5 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -111,6 +111,38 @@ static bool test_add_subkey(struct torture_context *tctx, return true; } +static bool test_del_recursive(struct torture_context *tctx, + const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + struct hive_key *subkey2; + const struct hive_key *root = (const struct hive_key *)test_data; + TALLOC_CTX *mem_ctx = tctx; + uint32_t data = 42; + + /* Create a new key under the root */ + error = hive_key_add_name(mem_ctx, root, "Parent Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + /* Create a new key under "Parent Key" */ + error = hive_key_add_name(mem_ctx, subkey, "Child Key", NULL, + NULL, &subkey2); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + /* Create a new value under "Child Key" */ + error = hive_key_set_value(subkey2, "Answer Recursive", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); + torture_assert_werr_ok(tctx, error, "hive_key_set_value"); + + /* Deleting "Parent Key" will also delete "Child Key" and the value. */ + error = hive_key_del(root, "Parent Key"); + torture_assert_werr_ok(tctx, error, "hive_key_del"); + + return true; +} + static bool test_flush_key(struct torture_context *tctx, void *test_data) { struct hive_key *root = (struct hive_key *)test_data; @@ -273,6 +305,11 @@ static void tcase_add_tests(struct torture_tcase *tcase) test_add_subkey); torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); + /* test_del_recursive() test must run before test_keyinfo_root(). + test_keyinfo_root() checks the number of subkeys, which verifies + the recursive delete worked properly. */ + torture_tcase_add_simple_test_const(tcase, "del_recursive", + test_del_recursive); torture_tcase_add_simple_test_const(tcase, "get_info", test_keyinfo_root); torture_tcase_add_simple_test(tcase, "get_info_nums", diff --git a/source4/samba4-knownfail b/source4/samba4-knownfail index 4d850caae5..e6a4ea1517 100644 --- a/source4/samba4-knownfail +++ b/source4/samba4-knownfail @@ -3,7 +3,7 @@ local.iconv.*.next_codepoint() base.delaywrite.finfo update on close base.delete.*.deltest20a base.delete.*.deltest20b -rpc.winreg +rpc.winreg.*security local.registry.*.security # Not implemented yet rpc.wkssvc rpc.handles.*.lsarpc-shared diff --git a/source4/torture/rpc/winreg.c b/source4/torture/rpc/winreg.c index 4695733671..8b602ef652 100644 --- a/source4/torture/rpc/winreg.c +++ b/source4/torture/rpc/winreg.c @@ -848,7 +848,6 @@ static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p, out: test_CloseKey(p, tctx, &new_handle); - test_Cleanup(p, tctx, handle, TEST_SUBSUBKEY_SD); test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD); test_RestoreSecurity(p, tctx, handle, key, sd_orig); @@ -971,7 +970,6 @@ static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p, out: test_CloseKey(p, tctx, &new_handle); - test_Cleanup(p, tctx, handle, TEST_SUBSUBKEY_SD); test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD); test_RestoreSecurity(p, tctx, handle, key, sd_orig); @@ -1386,27 +1384,6 @@ static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx, 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); - - 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, struct torture_context *tctx, struct policy_handle *handle, char *class) @@ -1443,10 +1420,12 @@ static bool test_QueryInfoKey(struct dcerpc_pipe *p, } static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx, - struct policy_handle *handle, int depth); + struct policy_handle *handle, int depth, + bool test_security); static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx, - struct policy_handle *handle, int depth) + struct policy_handle *handle, int depth, + bool test_security) { struct winreg_EnumKey r; struct winreg_StringBuf class, name; @@ -1479,7 +1458,8 @@ static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx, if (!test_OpenKey(p, tctx, handle, r.out.name->name, &key_handle)) { } else { - test_key(p, tctx, &key_handle, depth + 1); + test_key(p, tctx, &key_handle, + depth + 1, test_security); } } @@ -1676,7 +1656,8 @@ static bool test_InitiateSystemShutdownEx(struct torture_context *tctx, #define MAX_DEPTH 2 /* Only go this far down the tree */ static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx, - struct policy_handle *handle, int depth) + struct policy_handle *handle, int depth, + bool test_security) { if (depth == MAX_DEPTH) return true; @@ -1687,10 +1668,10 @@ static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx, if (!test_NotifyChangeKeyValue(p, tctx, handle)) { } - if (!test_GetKeySecurity(p, tctx, handle, NULL)) { + if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) { } - if (!test_EnumKey(p, tctx, handle, depth)) { + if (!test_EnumKey(p, tctx, handle, depth, test_security)) { } if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) { @@ -1703,13 +1684,85 @@ static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx, typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *); +static bool test_Open_Security(struct torture_context *tctx, + struct dcerpc_pipe *p, void *userdata) +{ + struct policy_handle handle, newhandle; + bool ret = true, created2 = false; + bool created4 = false; + struct winreg_OpenHKLM r; + + winreg_open_fn open_fn = userdata; + + r.in.system_name = 0; + r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r.out.handle = &handle; + + torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r), + "open"); + + test_Cleanup(p, tctx, &handle, TEST_KEY_BASE); + + if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) { + torture_comment(tctx, + "CreateKey (TEST_KEY_BASE) failed\n"); + } + + if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2, + NULL, &newhandle)) { + created2 = true; + } + + if (created2 && !test_CloseKey(p, tctx, &newhandle)) { + printf("CloseKey failed\n"); + ret = false; + } + + if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) { + created4 = true; + } + + if (created4 && !test_CloseKey(p, tctx, &newhandle)) { + printf("CloseKey failed\n"); + ret = false; + } + + if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) { + ret = false; + } + + if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) { + printf("DeleteKey failed\n"); + ret = false; + } + + if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) { + 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, tctx, &handle, MAX_DEPTH - 1, true)) { + ret = false; + } + } else { + if (!test_key(p, tctx, &handle, 0, true)) { + ret = false; + } + } + + test_Cleanup(p, tctx, &handle, TEST_KEY_BASE); + + return ret; +} + static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p, void *userdata) { struct policy_handle handle, newhandle; - bool ret = true, created = false, created2 = false, deleted = false; + bool ret = true, created = false, deleted = false; bool created3 = false, created_subkey = false; - bool created4 = false; struct winreg_OpenHKLM r; winreg_open_fn open_fn = userdata; @@ -1721,15 +1774,13 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p, torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r), "open"); - test_Cleanup(p, tctx, &handle, TEST_KEY1); - test_Cleanup(p, tctx, &handle, TEST_SUBSUBKEY_SD); - test_Cleanup(p, tctx, &handle, TEST_SUBKEY_SD); - test_Cleanup(p, tctx, &handle, TEST_KEY4); - 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, tctx, &handle, TEST_KEY_BASE, NULL)) { + torture_comment(tctx, + "CreateKey (TEST_KEY_BASE) failed\n"); + } + if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) { torture_comment(tctx, "CreateKey failed - not considering a failure\n"); @@ -1763,9 +1814,12 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p, } if (created && deleted && - test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle)) { + !_test_OpenKey(p, tctx, &handle, TEST_KEY1, + SEC_FLAG_MAXIMUM_ALLOWED, &newhandle, + WERR_BADFILE, NULL)) { torture_comment(tctx, - "DeleteKey failed (OpenKey after Delete worked)\n"); + "DeleteKey failed (OpenKey after Delete " + "did not return WERR_BADFILE)\n"); ret = false; } @@ -1774,40 +1828,6 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p, ret = false; } - if (created && test_CreateKey_sd(p, tctx, &handle, TEST_KEY2, - NULL, &newhandle)) { - created2 = true; - } - - if (created2 && !test_CloseKey(p, tctx, &newhandle)) { - printf("CloseKey failed\n"); - ret = false; - } - - if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) { - created4 = true; - } - - if (!created4 && !test_CloseKey(p, tctx, &newhandle)) { - printf("CloseKey failed\n"); - ret = false; - } - - if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) { - ret = false; - } - - if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) { - printf("DeleteKey failed\n"); - ret = false; - } - - - if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) { - printf("DeleteKey failed\n"); - ret = false; - } - if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) { created3 = true; } @@ -1818,19 +1838,6 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p, } 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; @@ -1838,13 +1845,13 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p, /* The HKCR hive has a very large fanout */ if (open_fn == (void *)dcerpc_winreg_OpenHKCR) { - if(!test_key(p, tctx, &handle, MAX_DEPTH - 1)) { + if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) { + ret = false; + } + } else { + if (!test_key(p, tctx, &handle, 0, false)) { ret = false; } - } - - if (!test_key(p, tctx, &handle, 0)) { - ret = false; } test_Cleanup(p, tctx, &handle, TEST_KEY_BASE); @@ -1854,14 +1861,6 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p, struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx) { - struct { - const char *name; - winreg_open_fn fn; - } open_fns[] = {{"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM }, - {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU }, - {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR }, - {"OpenHKCU", (winreg_open_fn)dcerpc_winreg_OpenHKCU }}; - int i; struct torture_rpc_tcase *tcase; struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG"); struct torture_test *test; @@ -1877,10 +1876,33 @@ struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx) test_InitiateSystemShutdownEx); test->dangerous = true; - for (i = 0; i < ARRAY_SIZE(open_fns); i++) { - torture_rpc_tcase_add_test_ex(tcase, open_fns[i].name, - test_Open, open_fns[i].fn); - } + /* Basic tests without security descriptors */ + torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic", + test_Open, + (winreg_open_fn)dcerpc_winreg_OpenHKLM); + torture_rpc_tcase_add_test_ex(tcase, "HKU-basic", + test_Open, + (winreg_open_fn)dcerpc_winreg_OpenHKU); + torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic", + test_Open, + (winreg_open_fn)dcerpc_winreg_OpenHKCR); + torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic", + test_Open, + (winreg_open_fn)dcerpc_winreg_OpenHKCU); + + /* Security descriptor tests */ + torture_rpc_tcase_add_test_ex(tcase, "HKLM-security", + test_Open_Security, + (winreg_open_fn)dcerpc_winreg_OpenHKLM); + torture_rpc_tcase_add_test_ex(tcase, "HKU-security", + test_Open_Security, + (winreg_open_fn)dcerpc_winreg_OpenHKU); + torture_rpc_tcase_add_test_ex(tcase, "HKCR-security", + test_Open_Security, + (winreg_open_fn)dcerpc_winreg_OpenHKCR); + torture_rpc_tcase_add_test_ex(tcase, "HKCU-security", + test_Open_Security, + (winreg_open_fn)dcerpc_winreg_OpenHKCU); return suite; } |