s4-torture: add test to check for Windows behavior of EnumValue call
authorGünther Deschner <gd@samba.org>
Wed, 15 Nov 2023 16:36:46 +0000 (17:36 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 20 Nov 2023 03:52:33 +0000 (03:52 +0000)
Guenther

Signed-off-by: Guenther Deschner <gd@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
selftest/knownfail.d/winreg [new file with mode: 0644]
source4/torture/rpc/winreg.c

diff --git a/selftest/knownfail.d/winreg b/selftest/knownfail.d/winreg
new file mode 100644 (file)
index 0000000..b1c55de
--- /dev/null
@@ -0,0 +1,5 @@
+^samba3.rpc.winreg.winreg.HKLM\(nt4_dc\)
+^samba3.rpc.winreg.winreg.HKCR\(nt4_dc\)
+^samba3.rpc.winreg.winreg.HKCU\(nt4_dc\)
+^samba3.rpc.winreg.winreg.HKU\(nt4_dc\)
+^samba4.rpc.winreg.*
index 28e435ca0856d1b11e67e1aa5bb7a66461753738..b0e153f5285bb62e40b8acb5b43626a58302e02f 100644 (file)
@@ -2068,6 +2068,90 @@ static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
        return true;
 }
 
+static bool test_EnumValue_one(struct dcerpc_binding_handle *b,
+                              struct torture_context *tctx,
+                              struct policy_handle *handle,
+                              int max_valnamelen)
+{
+       struct winreg_EnumValue r;
+       bool ret = true;
+       DATA_BLOB blob;
+
+       blob = data_blob_string_const("data_1");
+       torture_assert_goto(tctx,
+               test_SetValue(b, tctx, handle, "v1", REG_BINARY, blob.data, blob.length),
+               ret, done,
+               "test_SetValue failed");
+
+       blob = data_blob_string_const("data_2");
+       torture_assert_goto(tctx,
+               test_SetValue(b, tctx, handle, "v2", REG_BINARY, blob.data, blob.length),
+               ret, done,
+               "test_SetValue failed");
+
+       ZERO_STRUCT(r);
+
+       r.in.handle = handle;
+       r.in.enum_index = 0;
+
+       do {
+               enum winreg_Type type = REG_NONE;
+               uint32_t size = 0, zero = 0;
+               struct winreg_ValNameBuf name;
+               char n = '\0';
+
+               r.in.name = &name;
+               r.in.type = &type;
+               r.in.length = &zero;
+               r.in.size = &size;
+               r.out.name = &name;
+               r.out.size = &size;
+
+               name.name = &n;
+               name.size = max_valnamelen + 2;
+               name.length = 0;
+
+               r.in.value = talloc_array(tctx, uint8_t, 0);
+               torture_assert(tctx, r.in.value, "nomem");
+
+               torture_assert_ntstatus_ok_goto(tctx,
+                       dcerpc_winreg_EnumValue_r(b, tctx, &r),
+                       ret, done,
+                       "EnumValue failed");
+               if (W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
+                       break;
+               }
+               torture_assert_werr_equal_goto(tctx,
+                       r.out.result, WERR_MORE_DATA,
+                       ret, done,
+                       "unexpected return code");
+
+               *r.in.size = *r.out.size;
+               r.in.value = talloc_zero_array(tctx, uint8_t, *r.in.size);
+               torture_assert(tctx, r.in.value, "nomem");
+
+               torture_assert_ntstatus_ok_goto(tctx,
+                       dcerpc_winreg_EnumValue_r(b, tctx, &r),
+                       ret, done,
+                       "EnumValue failed");
+               torture_assert_werr_ok_goto(tctx, r.out.result,
+                       ret, done,
+                       "unexpected return code");
+
+               r.in.enum_index++;
+
+       } while (W_ERROR_IS_OK(r.out.result));
+
+       torture_assert_werr_equal_goto(tctx, r.out.result, WERR_NO_MORE_ITEMS,
+               ret, done,
+               "EnumValue failed");
+ done:
+       test_DeleteValue(b, tctx, handle, "v1");
+       test_DeleteValue(b, tctx, handle, "v2");
+
+       return ret;
+}
+
 static bool test_EnumValue(struct dcerpc_binding_handle *b,
                           struct torture_context *tctx,
                           struct policy_handle *handle, int max_valnamelen,
@@ -2227,6 +2311,10 @@ static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
        if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
        }
 
+       if (!test_EnumValue_one(b, tctx, handle, 0xff)) {
+               return false;
+       }
+
        test_CloseKey(b, tctx, handle);
 
        return true;
@@ -3009,6 +3097,8 @@ static bool test_key_base(struct torture_context *tctx,
                } else {
                        torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
                                "keytype test failed");
+                       torture_assert(tctx, test_EnumValue_one(b, tctx, &newhandle, 0xff),
+                               "simple EnumValue test failed");
                }
 
                if (!test_CloseKey(b, tctx, &newhandle)) {