diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/torture/rpc/winreg.c | 198 |
1 files changed, 190 insertions, 8 deletions
diff --git a/source4/torture/rpc/winreg.c b/source4/torture/rpc/winreg.c index 6743456b64..238ccba734 100644 --- a/source4/torture/rpc/winreg.c +++ b/source4/torture/rpc/winreg.c @@ -32,6 +32,10 @@ #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey" #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests" #define TEST_SUBKEY TEST_KEY3 "\\subkey" +#define TEST_SUBKEY_SD TEST_KEY4 "\\subkey_sd" +#define TEST_SUBSUBKEY_SD TEST_KEY4 "\\subkey_sd\\subsubkey_sd" + +#define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500" static void init_initshutdown_String(TALLOC_CTX *mem_ctx, struct initshutdown_String *name, @@ -302,6 +306,14 @@ static bool _test_SetKeySecurity(struct dcerpc_pipe *p, return true; } +static bool test_SetKeySecurity(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle, + struct security_descriptor *sd) +{ + return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK); +} + static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *handle) { @@ -410,19 +422,165 @@ static bool test_SecurityDescriptor(struct dcerpc_pipe *p, return ret; } -static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx, - struct policy_handle *handle, const char *key) +static bool test_dacl_ace_present(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle, + const struct security_ace *ace) +{ + struct security_descriptor *sd = NULL; + int i; + + if (!test_GetKeySecurity(p, tctx, handle, &sd)) { + return false; + } + + if (!sd || !sd->dacl) { + return false; + } + + for (i = 0; i < sd->dacl->num_aces; i++) { + if (security_ace_equal(&sd->dacl->aces[i], ace)) { + return true; + } + } + + return false; +} + +static bool test_RestoreSecurity(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle, + const char *key, + struct security_descriptor *sd) +{ + struct policy_handle new_handle; + bool ret = true; + + if (!test_OpenKey(p, tctx, handle, key, &new_handle)) { + return false; + } + + if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) { + ret = false; + } + + if (!test_CloseKey(p, tctx, &new_handle)) { + ret = false; + } + + return ret; +} + +static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct policy_handle *handle, + const char *key) { + /* get sd + add ace SEC_ACE_FLAG_CONTAINER_INHERIT + set sd + get sd + check ace + add subkey + get sd + check ace + add subsubkey + get sd + check ace + del subsubkey + del subkey + reset sd + */ + + struct security_descriptor *sd = NULL; + struct security_descriptor *sd_orig = NULL; + struct security_ace *ace = NULL; + struct policy_handle new_handle; NTSTATUS status; - struct winreg_DeleteKey r; + bool ret = true; - r.in.handle = handle; - init_winreg_String(&r.in.key, key); + torture_comment(tctx, "SecurityDescriptor inheritance\n"); - status = dcerpc_winreg_DeleteKey(p, tctx, &r); + if (!test_OpenKey(p, tctx, handle, key, &new_handle)) { + return false; + } - torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed"); - torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed"); + if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) { + return false; + } + + sd_orig = security_descriptor_copy(tctx, sd); + if (sd_orig == NULL) { + return false; + } + + ace = security_ace_create(tctx, + TEST_SID, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_STD_REQUIRED, + SEC_ACE_FLAG_CONTAINER_INHERIT); + + status = security_descriptor_dacl_add(sd, ace); + if (!NT_STATUS_IS_OK(status)) { + printf("failed to add ace: %s\n", nt_errstr(status)); + return false; + } + + /* FIXME: add further tests for these flags */ + sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ | + SEC_DESC_SACL_AUTO_INHERITED; + + if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) { + return false; + } + + if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) { + printf("new ACE not present!\n"); + return false; + } + + if (!test_CloseKey(p, tctx, &new_handle)) { + return false; + } + + if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) { + ret = false; + goto out; + } + + if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) { + ret = false; + goto out; + } + + if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) { + printf("inherited ACE not present!\n"); + ret = false; + goto out; + } + + test_CloseKey(p, tctx, &new_handle); + if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) { + ret = false; + goto out; + } + + if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) { + ret = false; + goto out; + } + + if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) { + printf("inherited ACE not present!\n"); + ret = false; + goto out; + } + + 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); return true; } @@ -440,9 +598,31 @@ static bool test_SecurityDescriptors(struct dcerpc_pipe *p, ret = false; } + if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) { + printf("test_SecurityDescriptorInheritance failed\n"); + ret = false; + } + return ret; } +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; + + r.in.handle = handle; + init_winreg_String(&r.in.key, key); + + status = dcerpc_winreg_DeleteKey(p, tctx, &r); + + torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed"); + torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed"); + + return true; +} + /* DeleteKey on a key with subkey(s) should * return WERR_ACCESS_DENIED. */ static bool test_DeleteKeyWithSubkey(struct dcerpc_pipe *p, @@ -779,6 +959,8 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p, "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); |