librpc: Change type of ‘u16string’ from ‘const uint16_t *’ to ‘const unsigned char *’
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Wed, 20 Dec 2023 22:51:19 +0000 (11:51 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 21 Dec 2023 23:48:46 +0000 (23:48 +0000)
A u16string is supposed to contain UTF‐16 code units, but
ndr_pull_u16string() and ndr_push_u16string() fail to correctly ensure
this on big‐endian systems. Code that relies on the u16string array
containing correct values will then fail.

Fix ndr_pull_u16string() and ndr_push_u16string() to work on big‐endian
systems, ensuring that other code can use these strings without having
to worry about first encoding them to little‐endian.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/util/charset/charset.h
lib/util/charset/util_unistr.c
librpc/ABI/ndr-4.0.0.sigs
librpc/ndr/libndr.h
librpc/ndr/ndr_string.c
librpc/tests/test_ndr_gmsa.c
pidl/lib/Parse/Pidl/Samba4/Python.pm
pidl/lib/Parse/Pidl/Typelist.pm
source4/librpc/rpc/pyrpc_util.c
source4/librpc/rpc/pyrpc_util.h

index aa6917347130a9cd8ea1c93457bc7b922a241ef2..12dc348bdb70e207ac3af24ae852edabfff573c0 100644 (file)
@@ -129,9 +129,9 @@ limited by 'n' bytes
 **/
 size_t utf16_null_terminated_len_n(const void *src, size_t n);
 
-uint16_t *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len);
-uint16_t *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str);
-uint16_t *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n);
+unsigned char *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len);
+unsigned char *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str);
+unsigned char *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n);
 
 char *strchr_m(const char *s, char c);
 /**
index fa1a100e596878416f5228c23cb5b12ab64f9f1d..830b4808c54793c0235a16249c10e68f1bf8d669 100644 (file)
@@ -243,9 +243,9 @@ size_t utf16_null_terminated_len_n(const void *src, size_t n)
        return len;
 }
 
-uint16_t *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len)
+unsigned char *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len)
 {
-       uint16_t *new_str = NULL;
+       unsigned char *new_str = NULL;
 
        /* Check for overflow. */
        if (len > SIZE_MAX - 2) {
@@ -263,22 +263,17 @@ uint16_t *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t le
 
        memcpy(new_str, str, len);
 
-       {
-               /*
-                * Ensure that the UTF‐16 string is
-                * null‐terminated.
-                */
-
-               char *new_bytes = (char *)new_str;
-
-               new_bytes[len] = '\0';
-               new_bytes[len + 1] = '\0';
-       }
+       /*
+        * Ensure that the UTF‐16 string is
+        * null‐terminated.
+        */
+       new_str[len] = '\0';
+       new_str[len + 1] = '\0';
 
        return new_str;
 }
 
-uint16_t *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str)
+unsigned char *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str)
 {
        if (str == NULL) {
                return NULL;
@@ -286,7 +281,7 @@ uint16_t *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str)
        return talloc_utf16_strlendup(mem_ctx, str, utf16_len(str));
 }
 
-uint16_t *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n)
+unsigned char *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n)
 {
        if (str == NULL) {
                return NULL;
index 66a1b64cf600caedd8a4a15a8da49450d546aa44..5474a5184b0dc9c52688c487254e928a533a2d3c 100644 (file)
@@ -81,7 +81,7 @@ ndr_print_svcctl_ServerType: void (struct ndr_print *, const char *, uint32_t)
 ndr_print_time_t: void (struct ndr_print *, const char *, time_t)
 ndr_print_timespec: void (struct ndr_print *, const char *, const struct timespec *)
 ndr_print_timeval: void (struct ndr_print *, const char *, const struct timeval *)
-ndr_print_u16string: void (struct ndr_print *, const char *, const uint16_t *)
+ndr_print_u16string: void (struct ndr_print *, const char *, const unsigned char *)
 ndr_print_udlong: void (struct ndr_print *, const char *, uint64_t)
 ndr_print_udlongr: void (struct ndr_print *, const char *, uint64_t)
 ndr_print_uid_t: void (struct ndr_print *, const char *, uid_t)
@@ -158,7 +158,7 @@ ndr_pull_time_t: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, time_t *)
 ndr_pull_timespec: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, struct timespec *)
 ndr_pull_timeval: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, struct timeval *)
 ndr_pull_trailer_align: enum ndr_err_code (struct ndr_pull *, size_t)
-ndr_pull_u16string: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, const uint16_t **)
+ndr_pull_u16string: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, const unsigned char **)
 ndr_pull_udlong: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, uint64_t *)
 ndr_pull_udlongr: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, uint64_t *)
 ndr_pull_uid_t: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, uid_t *)
@@ -234,7 +234,7 @@ ndr_push_time_t: enum ndr_err_code (struct ndr_push *, ndr_flags_type, time_t)
 ndr_push_timespec: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const struct timespec *)
 ndr_push_timeval: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const struct timeval *)
 ndr_push_trailer_align: enum ndr_err_code (struct ndr_push *, size_t)
-ndr_push_u16string: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const uint16_t *)
+ndr_push_u16string: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const unsigned char *)
 ndr_push_udlong: enum ndr_err_code (struct ndr_push *, ndr_flags_type, uint64_t)
 ndr_push_udlongr: enum ndr_err_code (struct ndr_push *, ndr_flags_type, uint64_t)
 ndr_push_uid_t: enum ndr_err_code (struct ndr_push *, ndr_flags_type, uid_t)
index adcbdf18c0c9e16f7deef7d2954f2c479f5b6c64..70dd01e49a673038a14241979e3f9eb80f19eb9b 100644 (file)
@@ -806,7 +806,7 @@ NDR_SCALAR_PROTO(DATA_BLOB, DATA_BLOB)
 NDR_SCALAR_PROTO(ipv4address, const char *)
 NDR_SCALAR_PROTO(ipv6address, const char *)
 NDR_SCALAR_PROTO(string, const char *)
-NDR_SCALAR_PROTO(u16string, const uint16_t *)
+NDR_SCALAR_PROTO(u16string, const unsigned char *)
 NDR_SCALAR_PROTO(double, double)
 
 enum ndr_err_code ndr_pull_policy_handle(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct policy_handle *r);
index 2ad139b420be04923d0f6bb5f2535c1f24482a3e..89ba8b0579bbe8b3e439d437969e4800447ac2ea 100644 (file)
@@ -481,9 +481,9 @@ _PUBLIC_ uint32_t ndr_size_string(int ret, const char * const* string, ndr_flags
 */
 _PUBLIC_ enum ndr_err_code ndr_pull_u16string(struct ndr_pull *ndr,
                                              ndr_flags_type ndr_flags,
-                                             const uint16_t **s)
+                                             const unsigned char **s)
 {
-       uint16_t *as = NULL;
+       unsigned char *as = NULL;
        const char *const src_str = (char *)ndr->data + ndr->offset;
        size_t src_len = 0;
 
@@ -544,7 +544,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_u16string(struct ndr_pull *ndr,
 */
 _PUBLIC_ enum ndr_err_code ndr_push_u16string(struct ndr_push *ndr,
                                              ndr_flags_type ndr_flags,
-                                             const uint16_t *s)
+                                             const unsigned char *s)
 {
        size_t s_len;
 
@@ -578,12 +578,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_u16string(struct ndr_push *ndr,
 
        switch (ndr->flags & LIBNDR_STRING_FLAGS) {
        case LIBNDR_FLAG_STR_NULLTERM:
-               NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)s, s_len));
+               NDR_CHECK(ndr_push_bytes(ndr, s, s_len));
                break;
 
        default:
                if (ndr->flags & LIBNDR_FLAG_REMAINING) {
-                       NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)s, s_len));
+                       NDR_CHECK(ndr_push_bytes(ndr, s, s_len));
                        break;
                }
 
@@ -600,11 +600,11 @@ _PUBLIC_ enum ndr_err_code ndr_push_u16string(struct ndr_push *ndr,
 
 _PUBLIC_ void ndr_print_u16string(struct ndr_print *ndr,
                                  const char *name,
-                                 const uint16_t *s)
+                                 const unsigned char *s)
 {
        return ndr_print_array_uint8(ndr,
                                     name,
-                                    (const uint8_t *)s,
+                                    s,
                                     utf16_len(s));
 }
 
index 9834ce7249ab4ace57848453750ba94af9e933db..67aa7c2ba2e5707d53d3dc7fa52e0139a94f1f51 100644 (file)
 #include "lib/replace/replace.h"
 
 #include "lib/util/attr.h"
+#include "lib/util/bytearray.h"
 #include "librpc/gen_ndr/ndr_gmsa.h"
 #include "librpc/gen_ndr/gmsa.h"
 
-static void assert_utf16_equal(const uint16_t *s1, const uint16_t *s2)
+static void assert_utf16_equal(const unsigned char *s1, const unsigned char *s2)
 {
        uint16_t c1;
        uint16_t c2;
+       size_t n = 0;
 
        assert_non_null(s1);
        assert_non_null(s2);
 
        do {
-               c1 = *s1++;
-               c2 = *s2++;
+               c1 = PULL_LE_U16(s1, n);
+               c2 = PULL_LE_U16(s2, n);
                assert_int_equal(c1, c2);
+               n += 2;
        } while (c1);
 }
 
@@ -82,23 +85,27 @@ static void test_managed_password_blob(void **state)
        const DATA_BLOB blob = {data, sizeof data};
 
        /* The UTF‐16 password contained in the blob. */
-       const uint16_t current_password[] = {
-               16781, 38893, 3992,  51373, 15923, 7932,  46125, 2558,  34452,
-               30290, 33629, 52175, 11237, 39662, 24149, 37397, 11132, 19333,
-               4008,  61917, 9782,  34431, 59396, 14004, 57456, 4643,  36018,
-               13809, 19377, 45615, 4500,  41906, 13134, 3922,  30149, 14594,
-               62323, 37627, 63819, 14101, 32226, 28757, 21916, 10026, 4483,
-               50729, 41961, 43820, 37254, 34397, 24410, 18164, 35324, 51276,
-               5135,  22021, 60285, 770,   63905, 6660,  52725, 4490,  8697,
-               38539, 36481, 5923,  48763, 22745, 32851, 6331,  17667, 14586,
-               22153, 50590, 31390, 25994, 64532, 26985, 7286,  6379,  64476,
-               11322, 59188, 19010, 55290, 24783, 14809, 6553,  1291,  20746,
-               50886, 62962, 23379, 44922, 7754,  6910,  29146, 63937, 24509,
-               38781, 60409, 17028, 43589, 36843, 39787, 8730,  7072,  20390,
-               26656, 25846, 19514, 26258, 27121, 38664, 5283,  59418, 35361,
-               47263, 48001, 31518, 4533,  21653, 63671, 65234, 25134, 3297,
-               50225, 38336, 0,
-       };
+       const unsigned char current_password[] = {
+               141, 65,  237, 151, 152, 15,  173, 200, 51,  62,  252, 30,  45,
+               180, 254, 9,   148, 134, 82,  118, 93,  131, 207, 203, 229, 43,
+               238, 154, 85,  94,  21,  146, 124, 43,  133, 75,  168, 15,  221,
+               241, 54,  38,  127, 134, 4,   232, 180, 54,  112, 224, 35,  18,
+               178, 140, 241, 53,  177, 75,  47,  178, 148, 17,  178, 163, 78,
+               51,  82,  15,  197, 117, 2,   57,  115, 243, 251, 146, 75,  249,
+               21,  55,  226, 125, 85,  112, 156, 85,  42,  39,  131, 17,  41,
+               198, 233, 163, 44,  171, 134, 145, 93,  134, 90,  95,  244, 70,
+               252, 137, 76,  200, 15,  20,  5,   86,  125, 235, 2,   3,   161,
+               249, 4,   26,  245, 205, 138, 17,  249, 33,  139, 150, 129, 142,
+               35,  23,  123, 190, 217, 88,  83,  128, 187, 24,  3,   69,  250,
+               56,  137, 86,  158, 197, 158, 122, 138, 101, 20,  252, 105, 105,
+               118, 28,  235, 24,  220, 251, 58,  44,  52,  231, 66,  74,  250,
+               215, 207, 96,  217, 57,  153, 25,  11,  5,   10,  81,  198, 198,
+               242, 245, 83,  91,  122, 175, 74,  30,  254, 26,  218, 113, 193,
+               249, 189, 95,  125, 151, 249, 235, 132, 66,  69,  170, 235, 143,
+               107, 155, 26,  34,  160, 27,  166, 79,  32,  104, 246, 100, 58,
+               76,  146, 102, 241, 105, 8,   151, 163, 20,  26,  232, 33,  138,
+               159, 184, 129, 187, 30,  123, 181, 17,  149, 84,  183, 248, 210,
+               254, 46,  98,  225, 12,  49,  196, 192, 149, 0,   0};
 
        DATA_BLOB packed_blob = data_blob_null;
 
index 57f8e8b5638f685423ae746fd8ac89611aa40926..c09ee4b784d45f0273c13ae8209037818ea2d820 100644 (file)
@@ -1706,7 +1706,7 @@ sub ConvertU16StringFromPythonData($$$$$)
 
        $self->pidl("{");
        $self->indent;
-       $self->pidl("uint16_t *str = NULL;");
+       $self->pidl("unsigned char *str = NULL;");
        $self->pidl("");
        $self->pidl("str = PyUtf16String_FromBytes(");
        $self->pidl("   $mem_ctx, $py_var);");
index 09d416f7b20637d3cb936a245f58f4552162697f..31ea19e357c56f04144de3b9193435cee0b4e234 100644 (file)
@@ -56,7 +56,7 @@ my %scalars = (
        "pointer"       => "void*",
        "DATA_BLOB"     => "DATA_BLOB",
        "string"        => "const char *",
-       "u16string"     => "const uint16_t *",
+       "u16string"     => "const unsigned char *",
        "string_array"  => "const char **",
        "time_t"        => "time_t",
        "uid_t"         => "uid_t",
index 98cfb73c1af59203df6ffe1f10b62f6ea3079e94..43c29af0e76ab636eb32b599c94b7f08f65b674f 100644 (file)
@@ -419,7 +419,7 @@ PyObject *PyString_FromStringOrNULL(const char *str)
        return PyUnicode_FromString(str);
 }
 
-PyObject *PyBytes_FromUtf16StringOrNULL(const uint16_t *str)
+PyObject *PyBytes_FromUtf16StringOrNULL(const unsigned char *str)
 {
        size_t len;
 
@@ -431,11 +431,11 @@ PyObject *PyBytes_FromUtf16StringOrNULL(const uint16_t *str)
        return PyBytes_FromStringAndSize((const char *)str, len);
 }
 
-uint16_t *PyUtf16String_FromBytes(TALLOC_CTX *mem_ctx, PyObject *value)
+unsigned char *PyUtf16String_FromBytes(TALLOC_CTX *mem_ctx, PyObject *value)
 {
        char *bytes = NULL;
        Py_ssize_t len = 0;
-       uint16_t *utf16_string = NULL;
+       unsigned char *utf16_string = NULL;
        int ret;
 
        ret = PyBytes_AsStringAndSize(value, &bytes, &len);
index 75b04f1d5fe1e08a1a4feeff5ab4642e8b174c82..73157fcba1c2d6ea9f4f5aa377ca6f209fc3f3e3 100644 (file)
@@ -59,9 +59,9 @@ PyObject *py_return_ndr_struct(const char *module_name, const char *type_name,
 
 PyObject *PyString_FromStringOrNULL(const char *str);
 
-PyObject *PyBytes_FromUtf16StringOrNULL(const uint16_t *str);
+PyObject *PyBytes_FromUtf16StringOrNULL(const unsigned char *str);
 
-uint16_t *PyUtf16String_FromBytes(TALLOC_CTX *mem_ctx, PyObject *value);
+unsigned char *PyUtf16String_FromBytes(TALLOC_CTX *mem_ctx, PyObject *value);
 
 PyObject *pyrpc_import_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
                             const void *in, const char *typename);