selftest: Improve error handling and perl style when setting up users in Samba4.pm
[Samba.git] / libcli / ldap / tests / ldap_message_test.c
blobf4b49bc47bcbe8c666e4880dabb81785cba46a4e
1 /*
2 * Unit tests for ldap_message.
4 * Copyright (C) Catalyst.NET Ltd 2020
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/>.
22 * from cmocka.c:
23 * These headers or their equivalents should be included prior to
24 * including
25 * this header file.
27 * #include <stdarg.h>
28 * #include <stddef.h>
29 * #include <setjmp.h>
31 * This allows test applications to use custom definitions of C standard
32 * library functions and types.
35 #include <stdarg.h>
36 #include <stddef.h>
37 #include <setjmp.h>
38 #include <cmocka.h>
40 #include "lib/util/attr.h"
41 #include "includes.h"
42 #include "lib/util/asn1.h"
43 #include "libcli/ldap/ldap_message.h"
44 #include "libcli/ldap/ldap_proto.h"
47 * declare the internal cmocka cm_print so we can output messages in
48 * sub unit format
50 void cm_print_error(const char * const format, ...);
52 * helper function and macro to compare an ldap error code constant with the
53 * coresponding nt_status code
55 #define NT_STATUS_LDAP_V(code) (0xF2000000 | code)
56 static void _assert_ldap_status_equal(
57 int a,
58 NTSTATUS b,
59 const char * const file,
60 const int line)
62 _assert_int_equal(NT_STATUS_LDAP_V(a), NT_STATUS_V(b), file, line);
65 #define assert_ldap_status_equal(a, b) \
66 _assert_ldap_status_equal((a), (b), __FILE__, __LINE__)
69 * helper function and macro to assert there were no errors in the last
70 * file operation
72 static void _assert_not_ferror(
73 FILE *f,
74 const char * const file,
75 const int line)
77 if (f == NULL || ferror(f)) {
78 cm_print_error("ferror (%d) %s\n", errno, strerror(errno));
79 _fail(file, line);
83 #define assert_not_ferror(f) \
84 _assert_not_ferror((f), __FILE__, __LINE__)
86 struct test_ctx {
89 static int setup(void **state)
91 struct test_ctx *test_ctx;
93 test_ctx = talloc_zero(NULL, struct test_ctx);
94 *state = test_ctx;
95 return 0;
98 static int teardown(void **state)
100 struct test_ctx *test_ctx = talloc_get_type_abort(*state,
101 struct test_ctx);
103 TALLOC_FREE(test_ctx);
104 return 0;
108 * Test that an empty request is handled correctly
110 static void test_empty_input(void **state)
112 struct test_ctx *test_ctx = talloc_get_type_abort(
113 *state,
114 struct test_ctx);
115 struct asn1_data *asn1;
116 struct ldap_message *ldap_msg;
117 NTSTATUS status;
118 uint8_t *buf = NULL;
119 size_t len = 0;
120 struct ldap_request_limits limits = {
121 .max_search_size = 256000,
125 asn1 = asn1_init(test_ctx, ASN1_MAX_TREE_DEPTH);
126 assert_non_null(asn1);
128 asn1_load_nocopy(asn1, buf, len);
130 ldap_msg = talloc(test_ctx, struct ldap_message);
131 assert_non_null(ldap_msg);
133 status = ldap_decode(
134 asn1, &limits, samba_ldap_control_handlers(), ldap_msg);
135 assert_ldap_status_equal(LDAP_PROTOCOL_ERROR, status);
139 * Check that a request is rejected it it's recursion depth exceeds
140 * the maximum value specified. This test uses a very deeply nested query,
141 * 10,000 or clauses.
144 static void test_recursion_depth_large(void **state)
146 struct test_ctx *test_ctx = talloc_get_type_abort(
147 *state,
148 struct test_ctx);
149 struct asn1_data *asn1;
150 struct ldap_message *ldap_msg;
151 NTSTATUS status;
152 FILE *f = NULL;
153 uint8_t *buffer = NULL;
154 const size_t BUFF_SIZE = 1048576;
155 size_t len;
156 struct ldap_request_limits limits = {
157 .max_search_size = 256000,
162 * Load a test data file containg 10,000 or clauses in encoded as
163 * an ASN.1 packet.
165 buffer = talloc_zero_array(test_ctx, uint8_t, BUFF_SIZE);
166 f = fopen("./libcli/ldap/tests/data/10000-or.dat", "r");
167 assert_not_ferror(f);
168 len = fread(buffer, sizeof(uint8_t), BUFF_SIZE, f);
169 assert_not_ferror(f);
170 assert_true(len > 0);
172 asn1 = asn1_init(test_ctx, ASN1_MAX_TREE_DEPTH);
173 assert_non_null(asn1);
174 asn1_load_nocopy(asn1, buffer, len);
176 ldap_msg = talloc(test_ctx, struct ldap_message);
177 assert_non_null(ldap_msg);
179 status = ldap_decode(
180 asn1, &limits, samba_ldap_control_handlers(), ldap_msg);
181 assert_ldap_status_equal(LDAP_PROTOCOL_ERROR, status);
185 * Check that a request is not rejected it it's recursion depth equals the
186 * maximum value
188 static void test_recursion_depth_equals_max(void **state)
190 struct test_ctx *test_ctx = talloc_get_type_abort(
191 *state,
192 struct test_ctx);
193 struct asn1_data *asn1;
194 struct ldap_message *ldap_msg;
195 NTSTATUS status;
196 FILE *f = NULL;
197 uint8_t *buffer = NULL;
198 const size_t BUFF_SIZE = 1048576;
199 size_t len;
200 struct ldap_request_limits limits = {
201 .max_search_size = 256000,
205 buffer = talloc_zero_array(test_ctx, uint8_t, BUFF_SIZE);
206 f = fopen("./libcli/ldap/tests/data/ldap-recursive.dat", "r");
207 assert_not_ferror(f);
208 len = fread(buffer, sizeof(uint8_t), BUFF_SIZE, f);
209 assert_not_ferror(f);
210 assert_true(len > 0);
212 asn1 = asn1_init(test_ctx, 4);
213 assert_non_null(asn1);
214 asn1_load_nocopy(asn1, buffer, len);
216 ldap_msg = talloc(test_ctx, struct ldap_message);
217 assert_non_null(ldap_msg);
219 status = ldap_decode(
220 asn1, &limits, samba_ldap_control_handlers(), ldap_msg);
221 assert_true(NT_STATUS_IS_OK(status));
225 * Check that a request is rejected it it's recursion depth is greater than the
226 * maximum value
228 static void test_recursion_depth_greater_than_max(void **state)
230 struct test_ctx *test_ctx = talloc_get_type_abort(
231 *state,
232 struct test_ctx);
233 struct asn1_data *asn1;
234 struct ldap_message *ldap_msg;
235 NTSTATUS status;
236 FILE *f = NULL;
237 uint8_t *buffer = NULL;
238 const size_t BUFF_SIZE = 1048576;
239 size_t len;
240 struct ldap_request_limits limits = {
241 .max_search_size = 256000,
245 buffer = talloc_zero_array(test_ctx, uint8_t, BUFF_SIZE);
246 f = fopen("./libcli/ldap/tests/data/ldap-recursive.dat", "r");
247 assert_not_ferror(f);
248 len = fread(buffer, sizeof(uint8_t), BUFF_SIZE, f);
249 assert_not_ferror(f);
250 assert_true(len > 0);
252 asn1 = asn1_init(test_ctx, 3);
253 assert_non_null(asn1);
254 asn1_load_nocopy(asn1, buffer, len);
256 ldap_msg = talloc(test_ctx, struct ldap_message);
257 assert_non_null(ldap_msg);
259 status = ldap_decode(
260 asn1, &limits, samba_ldap_control_handlers(), ldap_msg);
261 assert_ldap_status_equal(LDAP_PROTOCOL_ERROR, status);
264 int main(_UNUSED_ int argc, _UNUSED_ const char **argv)
266 const struct CMUnitTest tests[] = {
267 cmocka_unit_test_setup_teardown(
268 test_empty_input,
269 setup,
270 teardown),
271 cmocka_unit_test_setup_teardown(
272 test_recursion_depth_large,
273 setup,
274 teardown),
275 cmocka_unit_test_setup_teardown(
276 test_recursion_depth_equals_max,
277 setup,
278 teardown),
279 cmocka_unit_test_setup_teardown(
280 test_recursion_depth_greater_than_max,
281 setup,
282 teardown),
285 cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
286 return cmocka_run_group_tests(tests, NULL, NULL);