2 * Unix SMB/CIFS implementation.
4 * Copyright (C) 2018 Andreas Schneider <asn@samba.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "ldb_private.h"
29 static void test_ldb_dn_add_child_fmt(void **state
)
31 struct ldb_context
*ldb
= ldb_init(NULL
, NULL
);
33 struct ldb_dn
*dn
= ldb_dn_new(ldb
, ldb
, "dc=samba,dc=org");
35 assert_true(ldb_dn_add_child_fmt(dn
,
38 assert_string_equal("DC=X,dc=samba,dc=org",
39 ldb_dn_get_linearized(dn
));
41 assert_string_equal("DC=X,DC=SAMBA,DC=ORG",
42 ldb_dn_get_casefold(dn
));
46 static void test_ldb_dn_add_child_fmt2(void **state
)
48 struct ldb_context
*ldb
= ldb_init(NULL
, NULL
);
50 struct ldb_dn
*dn
= ldb_dn_new(ldb
, ldb
, "dc=samba,dc=org");
52 assert_true(ldb_dn_add_child_fmt(dn
,
55 assert_string_equal("DC=X,DC=Y,dc=samba,dc=org",
56 ldb_dn_get_linearized(dn
));
58 assert_string_equal("DC=X,DC=Y,DC=SAMBA,DC=ORG",
59 ldb_dn_get_casefold(dn
));
62 ldb_dn_get_comp_num(dn
));
66 static void test_ldb_dn_add_child_val(void **state
)
68 struct ldb_context
*ldb
= ldb_init(NULL
, NULL
);
70 struct ldb_dn
*dn
= ldb_dn_new(ldb
, ldb
, "dc=samba,dc=org");
71 struct ldb_val name
= {.data
= discard_const("X"),
75 assert_true(ldb_dn_add_child_val(dn
,
78 assert_string_equal("DC=X,dc=samba,dc=org",
79 ldb_dn_get_linearized(dn
));
81 assert_string_equal("DC=X,DC=SAMBA,DC=ORG",
82 ldb_dn_get_casefold(dn
));
86 static void test_ldb_dn_add_child_val2(void **state
)
88 struct ldb_context
*ldb
= ldb_init(NULL
, NULL
);
90 struct ldb_dn
*dn
= ldb_dn_new(ldb
, ldb
, "dc=samba,dc=org");
92 struct ldb_val name
= {.data
= discard_const("X,DC=Y"),
96 assert_true(ldb_dn_add_child_val(dn
,
99 assert_string_equal("DC=X\\,DC\\3DY,dc=samba,dc=org",
100 ldb_dn_get_linearized(dn
));
102 assert_string_equal("DC=X\\,DC\\3DY,DC=SAMBA,DC=ORG",
103 ldb_dn_get_casefold(dn
));
106 ldb_dn_get_comp_num(dn
));
110 struct explode_test
{
116 const char *linearized
;
117 const char *ext_linearized_1
;
121 static int extended_dn_read_ID(struct ldb_context
*ldb
, void *mem_ctx
,
122 const struct ldb_val
*in
, struct ldb_val
*out
)
125 /* Allow to check we can cope with validity checks */
126 if (in
->length
!= 4) {
131 out
->data
= talloc_memdup(mem_ctx
, in
->data
, in
->length
);
132 if (out
->data
== NULL
) {
139 /* write out (reused for both HEX and clear for now) */
140 static int extended_dn_write_ID(struct ldb_context
*ldb
, void *mem_ctx
,
141 const struct ldb_val
*in
, struct ldb_val
*out
)
145 out
->data
= talloc_memdup(mem_ctx
, in
->data
, in
->length
);
146 if (out
->data
== NULL
) {
153 static void test_ldb_dn_explode(void **state
)
156 struct ldb_context
*ldb
= ldb_init(NULL
, NULL
);
157 struct explode_test tests
[] = {
158 {"A=B", 1, 0, false, false, "A=B", "A=B", true},
159 {"", 0, 0, false, false, "", "", true},
160 {" ", -1, -1, false, false, " ", " ", false},
161 {"<>", 0, 0, false, false, "", NULL
, true},
162 {"<", 0, 0, false, false, "", NULL
, true},
163 {"<><", 0, 0, false, false, "", NULL
, true},
164 {"<><>", 0, 0, false, false, "", NULL
, true},
165 {"A=B,C=D", 2, 0, false, false, "A=B,C=D", "A=B,C=D", true},
166 {"<X=Y>A=B,C=D", -1, -1, false, false, "", NULL
, false},
167 {"<X=Y>;A=B,C=D", -1, -1, false, false, "A=B,C=D", NULL
, false},
168 {"<ID=ABC>;A=B,C=D", -1, -1, false, true, "A=B,C=D", NULL
, false},
169 {"<ID=ABCD>;A=B,C=D", 2, 1, false, false, "A=B,C=D", "<ID=ABCD>;A=B,C=D", true},
170 {"x=🔥", 1, 0, false, false, "x=🔥", "x=🔥", true},
171 {"@FOO", 0, 0, true, false, "@FOO", "@FOO", true},
174 struct ldb_dn_extended_syntax syntax
= {
176 .read_fn
= extended_dn_read_ID
,
177 .write_clear_fn
= extended_dn_write_ID
,
178 .write_hex_fn
= extended_dn_write_ID
181 ldb_dn_extended_add_syntax(ldb
, 0, &syntax
);
183 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++) {
186 const char *ext_linear
;
187 struct ldb_dn
*dn
= ldb_dn_new(ldb
, ldb
, tests
[i
].strdn
);
190 * special, invalid, linear, and ext_linear are set before
193 linear
= ldb_dn_get_linearized(dn
);
194 assert_true((linear
== NULL
) == (tests
[i
].linearized
== NULL
));
195 assert_string_equal(linear
,
196 tests
[i
].linearized
);
198 ext_linear
= ldb_dn_get_extended_linearized(ldb
, dn
, 1);
199 assert_true((ext_linear
== NULL
) ==
200 (tests
[i
].ext_linearized_1
== NULL
));
202 if (tests
[i
].ext_linearized_1
!= NULL
) {
203 assert_string_equal(ext_linear
,
204 tests
[i
].ext_linearized_1
);
206 assert_true(ldb_dn_is_special(dn
) == tests
[i
].special
);
207 assert_true(ldb_dn_is_valid(dn
) != tests
[i
].invalid
);
209 /* comp nums are set by explode */
210 result
= ldb_dn_validate(dn
);
211 print_error("string under test (%zu) «%s»: res %i lin «%s» ext «%s»\n",
212 i
, tests
[i
].strdn
, result
, linear
, ext_linear
);
214 assert_true(result
== tests
[i
].explode_result
);
215 assert_int_equal(ldb_dn_get_comp_num(dn
),
217 assert_int_equal(ldb_dn_get_extended_comp_num(dn
),
218 tests
[i
].ext_comp_num
);
223 const struct CMUnitTest tests
[] = {
224 cmocka_unit_test(test_ldb_dn_add_child_fmt
),
225 cmocka_unit_test(test_ldb_dn_add_child_fmt2
),
226 cmocka_unit_test(test_ldb_dn_add_child_val
),
227 cmocka_unit_test(test_ldb_dn_add_child_val2
),
228 cmocka_unit_test(test_ldb_dn_explode
),
231 cmocka_set_message_output(CM_OUTPUT_SUBUNIT
);
233 return cmocka_run_group_tests(tests
, NULL
, NULL
);