Line data Source code
1 : /*
2 : * Tests exercising the ldb_filter_attrs().
3 : *
4 : *
5 : * Copyright (C) Catalyst.NET Ltd 2017
6 : * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2019
7 : *
8 : * This program is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU General Public License as published by
10 : * the Free Software Foundation; either version 3 of the License, or
11 : * (at your option) any later version.
12 : *
13 : * This program is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU General Public License
19 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : *
21 : */
22 :
23 : /*
24 : * from cmocka.c:
25 : * These headers or their equivalents should be included prior to
26 : * including
27 : * this header file.
28 : *
29 : * #include <stdarg.h>
30 : * #include <stddef.h>
31 : * #include <setjmp.h>
32 : *
33 : * This allows test applications to use custom definitions of C standard
34 : * library functions and types.
35 : */
36 : #include <stdarg.h>
37 : #include <stddef.h>
38 : #include <stdint.h>
39 : #include <string.h>
40 : #include <setjmp.h>
41 : #include <cmocka.h>
42 :
43 : #include "../include/ldb.h"
44 : #include "../include/ldb_module.h"
45 :
46 : struct ldbtest_ctx {
47 : struct tevent_context *ev;
48 : struct ldb_context *ldb;
49 : };
50 :
51 : /*
52 : * NOTE WELL:
53 : *
54 : * This test checks the current behaviour of the function, however
55 : * this is not in a public ABI and many of the tested behaviours are
56 : * not ideal. If the behaviour is deliberately improved, this test
57 : * should be updated without worry to the new better behaviour.
58 : *
59 : * In particular the test is particularly to ensure the current
60 : * behaviour is memory-safe.
61 : */
62 :
63 14 : static int setup(void **state)
64 : {
65 14 : struct ldbtest_ctx *test_ctx;
66 :
67 14 : test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
68 14 : assert_non_null(test_ctx);
69 :
70 14 : test_ctx->ev = tevent_context_init(test_ctx);
71 14 : assert_non_null(test_ctx->ev);
72 :
73 14 : test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
74 14 : assert_non_null(test_ctx->ldb);
75 :
76 14 : *state = test_ctx;
77 14 : return 0;
78 : }
79 :
80 14 : static int teardown(void **state)
81 : {
82 14 : talloc_free(*state);
83 14 : return 0;
84 : }
85 :
86 :
87 : /*
88 : * Test against a record with only one attribute, matching the one in
89 : * the list
90 : */
91 1 : static void test_filter_attrs_one_attr_matched(void **state)
92 : {
93 1 : struct ldbtest_ctx *ctx = *state;
94 1 : int ret;
95 :
96 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
97 :
98 1 : const char *attrs[] = {"foo", NULL};
99 :
100 1 : char value[] = "The value.......end";
101 1 : struct ldb_val value_1 = {
102 : .data = (uint8_t *)value,
103 1 : .length = strlen(value)
104 : };
105 1 : struct ldb_message_element element_1 = {
106 : .name = "foo",
107 : .num_values = 1,
108 : .values = &value_1
109 : };
110 2 : struct ldb_message in = {
111 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
112 : .num_elements = 1,
113 : .elements = &element_1,
114 : };
115 :
116 1 : assert_non_null(in.dn);
117 :
118 1 : ret = ldb_filter_attrs(ctx->ldb,
119 : &in,
120 : attrs,
121 : filtered_msg);
122 1 : assert_int_equal(ret, LDB_SUCCESS);
123 1 : assert_non_null(filtered_msg);
124 :
125 : /*
126 : * assert the ldb_filter_attrs does not read or modify
127 : * filtered_msg.dn in this case
128 : */
129 1 : assert_null(filtered_msg->dn);
130 1 : assert_int_equal(filtered_msg->num_elements, 1);
131 1 : assert_string_equal(filtered_msg->elements[0].name, "foo");
132 1 : assert_int_equal(filtered_msg->elements[0].num_values, 1);
133 1 : assert_int_equal(filtered_msg->elements[0].values[0].length,
134 : strlen(value));
135 1 : assert_memory_equal(filtered_msg->elements[0].values[0].data,
136 : value, strlen(value));
137 1 : }
138 :
139 : /*
140 : * Test against a record with only one attribute, matching the one of
141 : * the multiple attributes in the list
142 : */
143 1 : static void test_filter_attrs_one_attr_matched_of_many(void **state)
144 : {
145 1 : struct ldbtest_ctx *ctx = *state;
146 1 : int ret;
147 :
148 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
149 :
150 1 : const char *attrs[] = {"foo", "bar", "baz", NULL};
151 :
152 1 : char value[] = "The value.......end";
153 1 : struct ldb_val value_1 = {
154 : .data = (uint8_t *)value,
155 1 : .length = strlen(value)
156 : };
157 1 : struct ldb_message_element element_1 = {
158 : .name = "foo",
159 : .num_values = 1,
160 : .values = &value_1
161 : };
162 2 : struct ldb_message in = {
163 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
164 : .num_elements = 1,
165 : .elements = &element_1,
166 : };
167 :
168 1 : assert_non_null(in.dn);
169 :
170 1 : ret = ldb_filter_attrs(ctx->ldb,
171 : &in,
172 : attrs,
173 : filtered_msg);
174 1 : assert_int_equal(ret, LDB_SUCCESS);
175 1 : assert_non_null(filtered_msg);
176 :
177 : /*
178 : * assert the ldb_filter_attrs does not read or modify
179 : * filtered_msg.dn in this case
180 : */
181 1 : assert_null(filtered_msg->dn);
182 1 : assert_int_equal(filtered_msg->num_elements, 1);
183 1 : assert_string_equal(filtered_msg->elements[0].name, "foo");
184 1 : assert_int_equal(filtered_msg->elements[0].num_values, 1);
185 1 : assert_int_equal(filtered_msg->elements[0].values[0].length,
186 : strlen(value));
187 1 : assert_memory_equal(filtered_msg->elements[0].values[0].data,
188 : value, strlen(value));
189 1 : }
190 :
191 : /*
192 : * Test against a record with only one attribute, matching both
193 : * attributes in the list
194 : */
195 1 : static void test_filter_attrs_two_attr_matched_attrs(void **state)
196 : {
197 1 : struct ldbtest_ctx *ctx = *state;
198 1 : int ret;
199 :
200 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
201 :
202 : /* deliberately the other order */
203 1 : const char *attrs[] = {"bar", "foo", NULL};
204 :
205 1 : char value1[] = "The value.......end";
206 1 : char value2[] = "The value..MUST.end";
207 1 : struct ldb_val value_1 = {
208 : .data = (uint8_t *)value1,
209 1 : .length = strlen(value1)
210 : };
211 1 : struct ldb_val value_2 = {
212 : .data = (uint8_t *)value2,
213 1 : .length = strlen(value2)
214 : };
215 :
216 : /* foo and bar are the other order to in attrs */
217 1 : struct ldb_message_element elements[] = {
218 : {
219 : .name = "foo",
220 : .num_values = 1,
221 : .values = &value_1
222 : },
223 : {
224 : .name = "bar",
225 : .num_values = 1,
226 : .values = &value_2
227 : }
228 : };
229 2 : struct ldb_message in = {
230 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
231 : .num_elements = 2,
232 : .elements = elements,
233 : };
234 :
235 1 : assert_non_null(in.dn);
236 :
237 1 : ret = ldb_filter_attrs(ctx->ldb,
238 : &in,
239 : attrs,
240 : filtered_msg);
241 1 : assert_int_equal(ret, LDB_SUCCESS);
242 1 : assert_non_null(filtered_msg);
243 1 : assert_int_equal(filtered_msg->num_elements, 2);
244 :
245 : /*
246 : * assert the ldb_filter_attrs does not read or modify
247 : * filtered_msg.dn in this case
248 : */
249 1 : assert_null(filtered_msg->dn);
250 :
251 : /* Assert that DB order is preserved */
252 1 : assert_string_equal(filtered_msg->elements[0].name, "foo");
253 1 : assert_int_equal(filtered_msg->elements[0].num_values, 1);
254 1 : assert_int_equal(filtered_msg->elements[0].values[0].length,
255 : strlen(value1));
256 1 : assert_memory_equal(filtered_msg->elements[0].values[0].data,
257 : value1, strlen(value1));
258 1 : assert_string_equal(filtered_msg->elements[1].name, "bar");
259 1 : assert_int_equal(filtered_msg->elements[1].num_values, 1);
260 1 : assert_int_equal(filtered_msg->elements[1].values[0].length,
261 : strlen(value2));
262 1 : assert_memory_equal(filtered_msg->elements[1].values[0].data,
263 : value2, strlen(value2));
264 1 : }
265 :
266 : /*
267 : * Test against a record with two attributes, only of which is in
268 : * the list
269 : */
270 1 : static void test_filter_attrs_two_attr_matched_one_attr(void **state)
271 : {
272 1 : struct ldbtest_ctx *ctx = *state;
273 1 : int ret;
274 :
275 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
276 :
277 : /* deliberately the other order */
278 1 : const char *attrs[] = {"bar", NULL};
279 :
280 1 : char value1[] = "The value.......end";
281 1 : char value2[] = "The value..MUST.end";
282 1 : struct ldb_val value_1 = {
283 : .data = (uint8_t *)value1,
284 1 : .length = strlen(value1)
285 : };
286 1 : struct ldb_val value_2 = {
287 : .data = (uint8_t *)value2,
288 1 : .length = strlen(value2)
289 : };
290 :
291 : /* foo and bar are the other order to in attrs */
292 1 : struct ldb_message_element elements[] = {
293 : {
294 : .name = "foo",
295 : .num_values = 1,
296 : .values = &value_1
297 : },
298 : {
299 : .name = "bar",
300 : .num_values = 1,
301 : .values = &value_2
302 : }
303 : };
304 2 : struct ldb_message in = {
305 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
306 : .num_elements = 2,
307 : .elements = elements,
308 : };
309 :
310 1 : assert_non_null(in.dn);
311 :
312 1 : ret = ldb_filter_attrs(ctx->ldb,
313 : &in,
314 : attrs,
315 : filtered_msg);
316 1 : assert_int_equal(ret, LDB_SUCCESS);
317 1 : assert_non_null(filtered_msg);
318 1 : assert_int_equal(filtered_msg->num_elements, 1);
319 :
320 : /*
321 : * assert the ldb_filter_attrs does not read or modify
322 : * filtered_msg.dn in this case
323 : */
324 1 : assert_null(filtered_msg->dn);
325 :
326 : /* Assert that DB order is preserved */
327 1 : assert_string_equal(filtered_msg->elements[0].name, "bar");
328 1 : assert_int_equal(filtered_msg->elements[0].num_values, 1);
329 1 : assert_int_equal(filtered_msg->elements[0].values[0].length,
330 : strlen(value2));
331 1 : assert_memory_equal(filtered_msg->elements[0].values[0].data,
332 : value2, strlen(value2));
333 1 : }
334 :
335 : /*
336 : * Test against a record with two attributes, both matching the one
337 : * specified attribute in the list (a corrupt record)
338 : */
339 1 : static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state)
340 : {
341 1 : struct ldbtest_ctx *ctx = *state;
342 1 : int ret;
343 :
344 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
345 :
346 : /* deliberately the other order */
347 1 : const char *attrs[] = {"bar", NULL};
348 :
349 1 : char value1[] = "The value.......end";
350 1 : char value2[] = "The value..MUST.end";
351 1 : struct ldb_val value_1 = {
352 : .data = (uint8_t *)value1,
353 1 : .length = strlen(value1)
354 : };
355 1 : struct ldb_val value_2 = {
356 : .data = (uint8_t *)value2,
357 1 : .length = strlen(value2)
358 : };
359 :
360 : /* foo and bar are the other order to in attrs */
361 1 : struct ldb_message_element elements[] = {
362 : {
363 : .name = "bar",
364 : .num_values = 1,
365 : .values = &value_1
366 : },
367 : {
368 : .name = "bar",
369 : .num_values = 1,
370 : .values = &value_2
371 : }
372 : };
373 2 : struct ldb_message in = {
374 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
375 : .num_elements = 2,
376 : .elements = elements,
377 : };
378 :
379 1 : assert_non_null(in.dn);
380 :
381 1 : ret = ldb_filter_attrs(ctx->ldb,
382 : &in,
383 : attrs,
384 : filtered_msg);
385 :
386 : /* This should fail the pidgenhole test */
387 1 : assert_int_equal(ret, -1);
388 1 : assert_null(filtered_msg->elements);
389 1 : }
390 :
391 : /*
392 : * Test against a record with two attributes, both matching the one
393 : * specified attribute in the list (a corrupt record)
394 : */
395 1 : static void test_filter_attrs_two_dup_attr_matched_dup(void **state)
396 : {
397 1 : struct ldbtest_ctx *ctx = *state;
398 1 : int ret;
399 :
400 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
401 :
402 1 : const char *attrs[] = {"bar", "bar", NULL};
403 :
404 1 : char value1[] = "The value.......end";
405 1 : char value2[] = "The value..MUST.end";
406 1 : struct ldb_val value_1 = {
407 : .data = (uint8_t *)value1,
408 1 : .length = strlen(value1)
409 : };
410 1 : struct ldb_val value_2 = {
411 : .data = (uint8_t *)value2,
412 1 : .length = strlen(value2)
413 : };
414 :
415 : /* foo and bar are the other order to in attrs */
416 1 : struct ldb_message_element elements[] = {
417 : {
418 : .name = "bar",
419 : .num_values = 1,
420 : .values = &value_1
421 : },
422 : {
423 : .name = "bar",
424 : .num_values = 1,
425 : .values = &value_2
426 : }
427 : };
428 2 : struct ldb_message in = {
429 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
430 : .num_elements = 2,
431 : .elements = elements,
432 : };
433 :
434 1 : assert_non_null(in.dn);
435 :
436 1 : ret = ldb_filter_attrs(ctx->ldb,
437 : &in,
438 : attrs,
439 : filtered_msg);
440 :
441 : /* This does not fail the pidgenhole test */
442 1 : assert_int_equal(ret, LDB_SUCCESS);
443 1 : assert_int_equal(filtered_msg->num_elements, 2);
444 :
445 : /* Assert that DB order is preserved */
446 1 : assert_string_equal(filtered_msg->elements[0].name, "bar");
447 1 : assert_int_equal(filtered_msg->elements[0].num_values, 1);
448 1 : assert_int_equal(filtered_msg->elements[0].values[0].length,
449 : strlen(value1));
450 1 : assert_memory_equal(filtered_msg->elements[0].values[0].data,
451 : value1, strlen(value1));
452 1 : assert_string_equal(filtered_msg->elements[1].name, "bar");
453 1 : assert_int_equal(filtered_msg->elements[1].num_values, 1);
454 1 : assert_int_equal(filtered_msg->elements[1].values[0].length,
455 : strlen(value2));
456 1 : assert_memory_equal(filtered_msg->elements[1].values[0].data,
457 : value2, strlen(value2));
458 1 : }
459 :
460 : /*
461 : * Test against a record with two attributes, both matching one of the
462 : * specified attributes in the list (a corrupt record)
463 : */
464 1 : static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state)
465 : {
466 1 : struct ldbtest_ctx *ctx = *state;
467 1 : int ret;
468 :
469 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
470 :
471 1 : const char *attrs[] = {"bar", "foo", NULL};
472 :
473 1 : char value1[] = "The value.......end";
474 1 : char value2[] = "The value..MUST.end";
475 1 : struct ldb_val value_1 = {
476 : .data = (uint8_t *)value1,
477 1 : .length = strlen(value1)
478 : };
479 1 : struct ldb_val value_2 = {
480 : .data = (uint8_t *)value2,
481 1 : .length = strlen(value2)
482 : };
483 :
484 : /* foo and bar are the other order to in attrs */
485 1 : struct ldb_message_element elements[] = {
486 : {
487 : .name = "bar",
488 : .num_values = 1,
489 : .values = &value_1
490 : },
491 : {
492 : .name = "bar",
493 : .num_values = 1,
494 : .values = &value_2
495 : }
496 : };
497 2 : struct ldb_message in = {
498 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
499 : .num_elements = 2,
500 : .elements = elements,
501 : };
502 :
503 1 : assert_non_null(in.dn);
504 :
505 1 : ret = ldb_filter_attrs(ctx->ldb,
506 : &in,
507 : attrs,
508 : filtered_msg);
509 :
510 : /* This does not fail the pidgenhole test */
511 1 : assert_int_equal(ret, LDB_SUCCESS);
512 1 : assert_int_equal(filtered_msg->num_elements, 2);
513 :
514 : /* Assert that DB order is preserved */
515 1 : assert_string_equal(filtered_msg->elements[0].name, "bar");
516 1 : assert_int_equal(filtered_msg->elements[0].num_values, 1);
517 1 : assert_int_equal(filtered_msg->elements[0].values[0].length,
518 : strlen(value1));
519 1 : assert_memory_equal(filtered_msg->elements[0].values[0].data,
520 : value1, strlen(value1));
521 1 : assert_string_equal(filtered_msg->elements[1].name, "bar");
522 1 : assert_int_equal(filtered_msg->elements[1].num_values, 1);
523 1 : assert_int_equal(filtered_msg->elements[1].values[0].length,
524 : strlen(value2));
525 1 : assert_memory_equal(filtered_msg->elements[1].values[0].data,
526 : value2, strlen(value2));
527 1 : }
528 :
529 : /*
530 : * Test against a record with two attributes against * (but not the
531 : * other named attribute) (a corrupt record)
532 : */
533 1 : static void test_filter_attrs_two_dup_attr_matched_star(void **state)
534 : {
535 1 : struct ldbtest_ctx *ctx = *state;
536 1 : int ret;
537 :
538 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
539 :
540 1 : const char *attrs[] = {"*", "foo", NULL};
541 :
542 1 : char value1[] = "The value.......end";
543 1 : char value2[] = "The value..MUST.end";
544 1 : struct ldb_val value_1 = {
545 : .data = (uint8_t *)value1,
546 1 : .length = strlen(value1)
547 : };
548 1 : struct ldb_val value_2 = {
549 : .data = (uint8_t *)value2,
550 1 : .length = strlen(value2)
551 : };
552 :
553 : /* foo and bar are the other order to in attrs */
554 1 : struct ldb_message_element elements[] = {
555 : {
556 : .name = "bar",
557 : .num_values = 1,
558 : .values = &value_1
559 : },
560 : {
561 : .name = "bar",
562 : .num_values = 1,
563 : .values = &value_2
564 : }
565 : };
566 2 : struct ldb_message in = {
567 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
568 : .num_elements = 2,
569 : .elements = elements,
570 : };
571 :
572 1 : assert_non_null(in.dn);
573 :
574 : /* Needed as * implies distinguishedName */
575 1 : filtered_msg->dn = in.dn;
576 :
577 1 : ret = ldb_filter_attrs(ctx->ldb,
578 : &in,
579 : attrs,
580 : filtered_msg);
581 :
582 : /* This does not fail the pidgenhole test */
583 1 : assert_int_equal(ret, LDB_SUCCESS);
584 1 : assert_int_equal(filtered_msg->num_elements, 3);
585 :
586 : /* Assert that DB order is preserved */
587 1 : assert_string_equal(filtered_msg->elements[0].name, "bar");
588 1 : assert_int_equal(filtered_msg->elements[0].num_values, 1);
589 1 : assert_int_equal(filtered_msg->elements[0].values[0].length,
590 : strlen(value1));
591 1 : assert_memory_equal(filtered_msg->elements[0].values[0].data,
592 : value1, strlen(value1));
593 1 : assert_string_equal(filtered_msg->elements[1].name, "bar");
594 1 : assert_int_equal(filtered_msg->elements[1].num_values, 1);
595 1 : assert_int_equal(filtered_msg->elements[1].values[0].length,
596 : strlen(value2));
597 1 : assert_memory_equal(filtered_msg->elements[1].values[0].data,
598 : value2, strlen(value2));
599 : /*
600 : * assert the ldb_filter_attrs does not modify filtered_msg.dn
601 : * in this case
602 : */
603 1 : assert_ptr_equal(filtered_msg->dn, in.dn);
604 1 : assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg,
605 : "distinguishedName",
606 : NULL),
607 : ldb_dn_get_linearized(in.dn));
608 1 : }
609 :
610 : /*
611 : * Test against a record with only one attribute, matching the * in
612 : * the list
613 : */
614 1 : static void test_filter_attrs_one_attr_matched_star(void **state)
615 : {
616 1 : struct ldbtest_ctx *ctx = *state;
617 1 : int ret;
618 :
619 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
620 :
621 1 : const char *attrs[] = {"*", NULL};
622 :
623 1 : char value[] = "The value.......end";
624 1 : struct ldb_val value_1 = {
625 : .data = (uint8_t *)value,
626 1 : .length = strlen(value)
627 : };
628 1 : struct ldb_message_element element_1 = {
629 : .name = "foo",
630 : .num_values = 1,
631 : .values = &value_1
632 : };
633 2 : struct ldb_message in = {
634 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
635 : .num_elements = 1,
636 : .elements = &element_1,
637 : };
638 :
639 1 : assert_non_null(in.dn);
640 :
641 : /* Needed as * implies distinguishedName */
642 1 : filtered_msg->dn = in.dn;
643 :
644 1 : ret = ldb_filter_attrs(ctx->ldb,
645 : &in,
646 : attrs,
647 : filtered_msg);
648 1 : assert_int_equal(ret, LDB_SUCCESS);
649 1 : assert_non_null(filtered_msg);
650 1 : assert_int_equal(filtered_msg->num_elements, 2);
651 :
652 : /*
653 : * assert the ldb_filter_attrs does not modify filtered_msg.dn
654 : * in this case
655 : */
656 1 : assert_ptr_equal(filtered_msg->dn, in.dn);
657 1 : assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg,
658 : "distinguishedName",
659 : NULL),
660 : ldb_dn_get_linearized(in.dn));
661 1 : assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg,
662 : "foo",
663 : NULL),
664 : (const char *)value);
665 1 : }
666 :
667 : /*
668 : * Test against a record with two attributes, matching the * in
669 : * the list
670 : */
671 1 : static void test_filter_attrs_two_attr_matched_star(void **state)
672 : {
673 1 : struct ldbtest_ctx *ctx = *state;
674 1 : int ret;
675 :
676 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
677 :
678 1 : const char *attrs[] = {"*", NULL};
679 :
680 1 : char value1[] = "The value.......end";
681 1 : char value2[] = "The value..MUST.end";
682 1 : struct ldb_val value_1 = {
683 : .data = (uint8_t *)value1,
684 1 : .length = strlen(value1)
685 : };
686 1 : struct ldb_val value_2 = {
687 : .data = (uint8_t *)value2,
688 1 : .length = strlen(value2)
689 : };
690 1 : struct ldb_message_element elements[] = {
691 : {
692 : .name = "foo",
693 : .num_values = 1,
694 : .values = &value_1
695 : },
696 : {
697 : .name = "bar",
698 : .num_values = 1,
699 : .values = &value_2
700 : }
701 : };
702 2 : struct ldb_message in = {
703 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
704 : .num_elements = 2,
705 : .elements = elements,
706 : };
707 :
708 1 : assert_non_null(in.dn);
709 :
710 : /* Needed as * implies distinguishedName */
711 1 : filtered_msg->dn = in.dn;
712 :
713 1 : ret = ldb_filter_attrs(ctx->ldb,
714 : &in,
715 : attrs,
716 : filtered_msg);
717 1 : assert_int_equal(ret, LDB_SUCCESS);
718 1 : assert_non_null(filtered_msg);
719 1 : assert_int_equal(filtered_msg->num_elements, 3);
720 :
721 : /*
722 : * assert the ldb_filter_attrs does not modify filtered_msg.dn
723 : * in this case
724 : */
725 1 : assert_ptr_equal(filtered_msg->dn, in.dn);
726 1 : assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg,
727 : "distinguishedName",
728 : NULL),
729 : ldb_dn_get_linearized(in.dn));
730 1 : assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg,
731 : "foo",
732 : NULL),
733 : (const char *)value1);
734 1 : assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg,
735 : "bar",
736 : NULL),
737 : (const char *)value2);
738 1 : }
739 :
740 : /*
741 : * Test against a record with only one attribute, matching the * in
742 : * the list, but without the DN being pre-filled. Fails due to need
743 : * to construct the distinguishedName
744 : */
745 1 : static void test_filter_attrs_one_attr_matched_star_no_dn(void **state)
746 : {
747 1 : struct ldbtest_ctx *ctx = *state;
748 1 : int ret;
749 :
750 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
751 :
752 1 : const char *attrs[] = {"*", NULL};
753 :
754 1 : char value[] = "The value.......end";
755 1 : struct ldb_val value_1 = {
756 : .data = (uint8_t *)value,
757 1 : .length = strlen(value)
758 : };
759 1 : struct ldb_message_element element_1 = {
760 : .name = "foo",
761 : .num_values = 1,
762 : .values = &value_1
763 : };
764 2 : struct ldb_message in = {
765 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
766 : .num_elements = 1,
767 : .elements = &element_1,
768 : };
769 :
770 1 : assert_non_null(in.dn);
771 :
772 1 : ret = ldb_filter_attrs(ctx->ldb,
773 : &in,
774 : attrs,
775 : filtered_msg);
776 1 : assert_int_equal(ret, -1);
777 1 : assert_null(filtered_msg->elements);
778 1 : }
779 :
780 : /*
781 : * Test against a record with only one attribute, matching the * in
782 : * the list plus requsesting distinguishedName
783 : */
784 1 : static void test_filter_attrs_one_attr_matched_star_dn(void **state)
785 : {
786 1 : struct ldbtest_ctx *ctx = *state;
787 1 : int ret;
788 :
789 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
790 :
791 1 : const char *attrs[] = {"*", "distinguishedName", NULL};
792 :
793 1 : char value[] = "The value.......end";
794 1 : struct ldb_val value_1 = {
795 : .data = (uint8_t *)value,
796 1 : .length = strlen(value)
797 : };
798 1 : struct ldb_message_element element_1 = {
799 : .name = "foo",
800 : .num_values = 1,
801 : .values = &value_1
802 : };
803 2 : struct ldb_message in = {
804 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
805 : .num_elements = 1,
806 : .elements = &element_1,
807 : };
808 :
809 1 : assert_non_null(in.dn);
810 :
811 : /* Needed for distinguishedName */
812 1 : filtered_msg->dn = in.dn;
813 :
814 1 : ret = ldb_filter_attrs(ctx->ldb,
815 : &in,
816 : attrs,
817 : filtered_msg);
818 1 : assert_int_equal(ret, LDB_SUCCESS);
819 1 : assert_non_null(filtered_msg);
820 1 : assert_int_equal(filtered_msg->num_elements, 2);
821 :
822 : /* show that ldb_filter_attrs does not modify in.dn */
823 1 : assert_ptr_equal(filtered_msg->dn, in.dn);
824 :
825 1 : assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg,
826 : "distinguishedName",
827 : NULL),
828 : ldb_dn_get_linearized(in.dn));
829 1 : assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg,
830 : "foo",
831 : NULL),
832 : (const char *)value);
833 1 : }
834 :
835 : /*
836 : * Test against a record with only one attribute, but returning
837 : * distinguishedName from the list (only)
838 : */
839 1 : static void test_filter_attrs_one_attr_matched_dn(void **state)
840 : {
841 1 : struct ldbtest_ctx *ctx = *state;
842 1 : int ret;
843 :
844 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
845 :
846 1 : const char *attrs[] = {"distinguishedName", NULL};
847 :
848 1 : char value[] = "The value.......end";
849 1 : struct ldb_val value_1 = {
850 : .data = (uint8_t *)value,
851 1 : .length = strlen(value)
852 : };
853 1 : struct ldb_message_element element_1 = {
854 : .name = "foo",
855 : .num_values = 1,
856 : .values = &value_1
857 : };
858 2 : struct ldb_message in = {
859 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
860 : .num_elements = 1,
861 : .elements = &element_1,
862 : };
863 :
864 1 : assert_non_null(in.dn);
865 :
866 : /* Needed for distinguishedName */
867 1 : filtered_msg->dn = in.dn;
868 :
869 1 : ret = ldb_filter_attrs(ctx->ldb,
870 : &in,
871 : attrs,
872 : filtered_msg);
873 1 : assert_int_equal(ret, LDB_SUCCESS);
874 1 : assert_non_null(filtered_msg);
875 1 : assert_int_equal(filtered_msg->num_elements, 1);
876 :
877 : /* show that ldb_filter_attrs does not modify in.dn */
878 1 : assert_ptr_equal(filtered_msg->dn, in.dn);
879 1 : assert_string_equal(filtered_msg->elements[0].name, "distinguishedName");
880 1 : assert_int_equal(filtered_msg->elements[0].num_values, 1);
881 1 : assert_string_equal((const char *)filtered_msg->elements[0].values[0].data,
882 : ldb_dn_get_linearized(in.dn));
883 1 : }
884 :
885 : /*
886 : * Test against a record with only one attribute, not matching the
887 : * empty attribute list
888 : */
889 1 : static void test_filter_attrs_one_attr_empty_list(void **state)
890 : {
891 1 : struct ldbtest_ctx *ctx = *state;
892 1 : int ret;
893 :
894 1 : struct ldb_message *filtered_msg = ldb_msg_new(ctx);
895 :
896 1 : const char *attrs[] = {NULL};
897 :
898 1 : char value[] = "The value.......end";
899 1 : struct ldb_val value_1 = {
900 : .data = (uint8_t *)value,
901 1 : .length = strlen(value)
902 : };
903 1 : struct ldb_message_element element_1 = {
904 : .name = "foo",
905 : .num_values = 1,
906 : .values = &value_1
907 : };
908 2 : struct ldb_message in = {
909 1 : .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"),
910 : .num_elements = 1,
911 : .elements = &element_1,
912 : };
913 :
914 1 : assert_non_null(in.dn);
915 :
916 1 : ret = ldb_filter_attrs(ctx->ldb,
917 : &in,
918 : attrs,
919 : filtered_msg);
920 1 : assert_int_equal(ret, LDB_SUCCESS);
921 1 : assert_non_null(filtered_msg);
922 1 : assert_int_equal(filtered_msg->num_elements, 0);
923 1 : assert_null(filtered_msg->dn);
924 1 : assert_null(filtered_msg->elements);
925 1 : }
926 :
927 1 : int main(int argc, const char **argv)
928 : {
929 1 : const struct CMUnitTest tests[] = {
930 : cmocka_unit_test_setup_teardown(
931 : test_filter_attrs_one_attr_matched,
932 : setup,
933 : teardown),
934 : cmocka_unit_test_setup_teardown(
935 : test_filter_attrs_one_attr_matched_of_many,
936 : setup,
937 : teardown),
938 : cmocka_unit_test_setup_teardown(
939 : test_filter_attrs_two_attr_matched_attrs,
940 : setup,
941 : teardown),
942 : cmocka_unit_test_setup_teardown(
943 : test_filter_attrs_two_attr_matched_one_attr,
944 : setup,
945 : teardown),
946 : cmocka_unit_test_setup_teardown(
947 : test_filter_attrs_two_dup_attr_matched_one_attr,
948 : setup,
949 : teardown),
950 : cmocka_unit_test_setup_teardown(
951 : test_filter_attrs_two_dup_attr_matched_dup,
952 : setup,
953 : teardown),
954 : cmocka_unit_test_setup_teardown(
955 : test_filter_attrs_two_dup_attr_matched_one_of_two,
956 : setup,
957 : teardown),
958 : cmocka_unit_test_setup_teardown(
959 : test_filter_attrs_two_dup_attr_matched_star,
960 : setup,
961 : teardown),
962 : cmocka_unit_test_setup_teardown(
963 : test_filter_attrs_one_attr_matched_star,
964 : setup,
965 : teardown),
966 : cmocka_unit_test_setup_teardown(
967 : test_filter_attrs_two_attr_matched_star,
968 : setup,
969 : teardown),
970 : cmocka_unit_test_setup_teardown(
971 : test_filter_attrs_one_attr_matched_star_no_dn,
972 : setup,
973 : teardown),
974 : cmocka_unit_test_setup_teardown(
975 : test_filter_attrs_one_attr_matched_star_dn,
976 : setup,
977 : teardown),
978 : cmocka_unit_test_setup_teardown(
979 : test_filter_attrs_one_attr_matched_dn,
980 : setup,
981 : teardown),
982 : cmocka_unit_test_setup_teardown(
983 : test_filter_attrs_one_attr_empty_list,
984 : setup,
985 : teardown),
986 : };
987 :
988 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
989 :
990 1 : return cmocka_run_group_tests(tests, NULL, NULL);
991 : }
|