summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/registry/dir.c60
-rw-r--r--source4/lib/registry/ldb.c143
-rw-r--r--source4/lib/registry/regf.c53
-rw-r--r--source4/lib/registry/tests/hive.c37
-rw-r--r--source4/samba4-knownfail2
-rw-r--r--source4/torture/rpc/winreg.c230
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;
}