summaryrefslogtreecommitdiffstats
path: root/source4
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2009-10-21 02:16:32 +0200
committerKarolin Seeger <kseeger@samba.org>2009-11-26 11:39:42 +0100
commita2c1b1dcaa33c14ae9b57716d7888f901abaf234 (patch)
tree98cd951d94b9caea66fd593a0ef3f029ae9776ae /source4
parent1de792f2e815b8092666be429b0d491221114ec6 (diff)
downloadsamba-a2c1b1dcaa33c14ae9b57716d7888f901abaf234.tar.gz
samba-a2c1b1dcaa33c14ae9b57716d7888f901abaf234.tar.xz
samba-a2c1b1dcaa33c14ae9b57716d7888f901abaf234.zip
s4-smbtorture: test whether an lsa_EnumTrustDom implementation would hang up a client.
Guenther (cherry picked from commit 48520b2274638bde88b08361197c1056936bcba0) (cherry picked from commit 1500ee66e7b8d4d0644762aebed9be63b7cacb0b)
Diffstat (limited to 'source4')
-rw-r--r--source4/torture/rpc/lsa.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
index 9cee4e2f0c9..710f4c53d2f 100644
--- a/source4/torture/rpc/lsa.c
+++ b/source4/torture/rpc/lsa.c
@@ -2026,20 +2026,39 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
{
struct lsa_EnumTrustDom r;
NTSTATUS enum_status;
- uint32_t resume_handle = 0;
+ uint32_t in_resume_handle = 0;
+ uint32_t out_resume_handle;
struct lsa_DomainList domains;
bool ret = true;
torture_comment(tctx, "\nTesting EnumTrustDom\n");
r.in.handle = handle;
- r.in.resume_handle = &resume_handle;
+ r.in.resume_handle = &in_resume_handle;
r.in.max_size = 0;
r.out.domains = &domains;
- r.out.resume_handle = &resume_handle;
+ r.out.resume_handle = &out_resume_handle;
enum_status = dcerpc_lsa_EnumTrustDom(p, tctx, &r);
+ /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
+ * always be larger than the previous input resume handle, in
+ * particular when hitting the last query it is vital to set the
+ * resume handle correctly to avoid infinite client loops, as
+ * seen e.g. with Windows XP SP3 when resume handle is 0 and
+ * status is NT_STATUS_OK - gd */
+
+ if (NT_STATUS_IS_OK(enum_status) ||
+ NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES) ||
+ NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES))
+ {
+ if (out_resume_handle <= in_resume_handle) {
+ torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
+ out_resume_handle, in_resume_handle);
+ return false;
+ }
+ }
+
if (NT_STATUS_IS_OK(enum_status)) {
if (domains.count == 0) {
torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
@@ -2051,17 +2070,35 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
}
/* Start from the bottom again */
- resume_handle = 0;
+ in_resume_handle = 0;
do {
r.in.handle = handle;
- r.in.resume_handle = &resume_handle;
+ r.in.resume_handle = &in_resume_handle;
r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
r.out.domains = &domains;
- r.out.resume_handle = &resume_handle;
+ r.out.resume_handle = &out_resume_handle;
enum_status = dcerpc_lsa_EnumTrustDom(p, tctx, &r);
+ /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
+ * always be larger than the previous input resume handle, in
+ * particular when hitting the last query it is vital to set the
+ * resume handle correctly to avoid infinite client loops, as
+ * seen e.g. with Windows XP SP3 when resume handle is 0 and
+ * status is NT_STATUS_OK - gd */
+
+ if (NT_STATUS_IS_OK(enum_status) ||
+ NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES) ||
+ NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES))
+ {
+ if (out_resume_handle <= in_resume_handle) {
+ torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
+ out_resume_handle, in_resume_handle);
+ return false;
+ }
+ }
+
/* NO_MORE_ENTRIES is allowed */
if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) {
if (domains.count == 0) {
@@ -2090,6 +2127,8 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
ret &= test_query_each_TrustDom(p, tctx, handle, &domains);
+ in_resume_handle = out_resume_handle;
+
} while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)));
return ret;