Line data Source code
1 : /*
2 : * Tests exercising ldb_filter_attrs_in_place().
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 13 : static void msg_add_dn(struct ldb_message *msg)
87 : {
88 13 : const char *dn_attr = "distinguishedName";
89 13 : char *dn = NULL;
90 13 : int ret;
91 :
92 13 : assert_null(ldb_msg_find_element(msg, dn_attr));
93 :
94 13 : assert_non_null(msg->dn);
95 13 : dn = ldb_dn_alloc_linearized(msg, msg->dn);
96 13 : assert_non_null(dn);
97 :
98 : /*
99 : * The message's elements must be talloc allocated to call
100 : * ldb_msg_add_steal_string().
101 : */
102 13 : msg->elements = talloc_memdup(msg,
103 : msg->elements,
104 : msg->num_elements * sizeof(msg->elements[0]));
105 13 : assert_non_null(msg->elements);
106 :
107 13 : ret = ldb_msg_add_steal_string(msg, dn_attr, dn);
108 13 : assert_int_equal(ret, LDB_SUCCESS);
109 13 : }
110 :
111 : /*
112 : * Test against a record with only one attribute, matching the one in
113 : * the list
114 : */
115 1 : static void test_filter_attrs_in_place_one_attr_matched(void **state)
116 : {
117 1 : struct ldbtest_ctx *ctx = *state;
118 1 : int ret;
119 :
120 1 : struct ldb_message *msg = ldb_msg_new(ctx);
121 :
122 1 : const char *attrs[] = {"foo", NULL};
123 :
124 1 : char value[] = "The value.......end";
125 1 : struct ldb_val value_1 = {
126 : .data = (uint8_t *)value,
127 1 : .length = strlen(value)
128 : };
129 1 : struct ldb_message_element element_1 = {
130 : .name = "foo",
131 : .num_values = 1,
132 : .values = &value_1
133 : };
134 :
135 1 : assert_non_null(msg);
136 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
137 1 : msg->num_elements = 1;
138 1 : msg->elements = &element_1;
139 :
140 1 : assert_non_null(msg->dn);
141 1 : msg_add_dn(msg);
142 :
143 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
144 1 : assert_int_equal(ret, LDB_SUCCESS);
145 :
146 1 : assert_non_null(msg->dn);
147 1 : assert_int_equal(msg->num_elements, 1);
148 1 : assert_string_equal(msg->elements[0].name, "foo");
149 1 : assert_int_equal(msg->elements[0].num_values, 1);
150 1 : assert_int_equal(msg->elements[0].values[0].length,
151 : strlen(value));
152 1 : assert_memory_equal(msg->elements[0].values[0].data,
153 : value, strlen(value));
154 1 : }
155 :
156 : /*
157 : * Test against a record with only one attribute, matching the one of
158 : * the multiple attributes in the list
159 : */
160 1 : static void test_filter_attrs_in_place_one_attr_matched_of_many(void **state)
161 : {
162 1 : struct ldbtest_ctx *ctx = *state;
163 1 : int ret;
164 :
165 1 : struct ldb_message *msg = ldb_msg_new(ctx);
166 :
167 1 : const char *attrs[] = {"foo", "bar", "baz", NULL};
168 :
169 1 : char value[] = "The value.......end";
170 1 : struct ldb_val value_1 = {
171 : .data = (uint8_t *)value,
172 1 : .length = strlen(value)
173 : };
174 1 : struct ldb_message_element element_1 = {
175 : .name = "foo",
176 : .num_values = 1,
177 : .values = &value_1
178 : };
179 :
180 1 : assert_non_null(msg);
181 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
182 1 : msg->num_elements = 1;
183 1 : msg->elements = &element_1;
184 :
185 1 : assert_non_null(msg->dn);
186 1 : msg_add_dn(msg);
187 :
188 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
189 1 : assert_int_equal(ret, LDB_SUCCESS);
190 :
191 1 : assert_non_null(msg->dn);
192 1 : assert_int_equal(msg->num_elements, 1);
193 1 : assert_string_equal(msg->elements[0].name, "foo");
194 1 : assert_int_equal(msg->elements[0].num_values, 1);
195 1 : assert_int_equal(msg->elements[0].values[0].length,
196 : strlen(value));
197 1 : assert_memory_equal(msg->elements[0].values[0].data,
198 : value, strlen(value));
199 1 : }
200 :
201 : /*
202 : * Test against a record with only one attribute, matching both
203 : * attributes in the list
204 : */
205 1 : static void test_filter_attrs_in_place_two_attr_matched_attrs(void **state)
206 : {
207 1 : struct ldbtest_ctx *ctx = *state;
208 1 : int ret;
209 :
210 1 : struct ldb_message *msg = ldb_msg_new(ctx);
211 :
212 : /* deliberately the other order */
213 1 : const char *attrs[] = {"bar", "foo", NULL};
214 :
215 1 : char value1[] = "The value.......end";
216 1 : char value2[] = "The value..MUST.end";
217 1 : struct ldb_val value_1 = {
218 : .data = (uint8_t *)value1,
219 1 : .length = strlen(value1)
220 : };
221 1 : struct ldb_val value_2 = {
222 : .data = (uint8_t *)value2,
223 1 : .length = strlen(value2)
224 : };
225 :
226 : /* foo and bar are the other order to in attrs */
227 1 : struct ldb_message_element elements[] = {
228 : {
229 : .name = "foo",
230 : .num_values = 1,
231 : .values = &value_1
232 : },
233 : {
234 : .name = "bar",
235 : .num_values = 1,
236 : .values = &value_2
237 : }
238 : };
239 :
240 1 : assert_non_null(msg);
241 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
242 1 : msg->num_elements = 2;
243 1 : msg->elements = elements;
244 :
245 1 : assert_non_null(msg->dn);
246 1 : msg_add_dn(msg);
247 :
248 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
249 1 : assert_int_equal(ret, LDB_SUCCESS);
250 1 : assert_int_equal(msg->num_elements, 2);
251 :
252 1 : assert_non_null(msg->dn);
253 :
254 : /* Assert that DB order is preserved */
255 1 : assert_string_equal(msg->elements[0].name, "foo");
256 1 : assert_int_equal(msg->elements[0].num_values, 1);
257 1 : assert_int_equal(msg->elements[0].values[0].length,
258 : strlen(value1));
259 1 : assert_memory_equal(msg->elements[0].values[0].data,
260 : value1, strlen(value1));
261 1 : assert_string_equal(msg->elements[1].name, "bar");
262 1 : assert_int_equal(msg->elements[1].num_values, 1);
263 1 : assert_int_equal(msg->elements[1].values[0].length,
264 : strlen(value2));
265 1 : assert_memory_equal(msg->elements[1].values[0].data,
266 : value2, strlen(value2));
267 1 : }
268 :
269 : /*
270 : * Test against a record with two attributes, only of which is in
271 : * the list
272 : */
273 1 : static void test_filter_attrs_in_place_two_attr_matched_one_attr(void **state)
274 : {
275 1 : struct ldbtest_ctx *ctx = *state;
276 1 : int ret;
277 :
278 1 : struct ldb_message *msg = ldb_msg_new(ctx);
279 :
280 1 : const char *attrs[] = {"bar", NULL};
281 :
282 1 : char value1[] = "The value.......end";
283 1 : char value2[] = "The value..MUST.end";
284 1 : struct ldb_val value_1 = {
285 : .data = (uint8_t *)value1,
286 1 : .length = strlen(value1)
287 : };
288 1 : struct ldb_val value_2 = {
289 : .data = (uint8_t *)value2,
290 1 : .length = strlen(value2)
291 : };
292 :
293 1 : struct ldb_message_element elements[] = {
294 : {
295 : .name = "foo",
296 : .num_values = 1,
297 : .values = &value_1
298 : },
299 : {
300 : .name = "bar",
301 : .num_values = 1,
302 : .values = &value_2
303 : }
304 : };
305 :
306 1 : assert_non_null(msg);
307 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
308 1 : msg->num_elements = 2;
309 1 : msg->elements = elements;
310 :
311 1 : assert_non_null(msg->dn);
312 1 : msg_add_dn(msg);
313 :
314 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
315 1 : assert_int_equal(ret, LDB_SUCCESS);
316 1 : assert_int_equal(msg->num_elements, 1);
317 :
318 1 : assert_non_null(msg->dn);
319 :
320 : /* Assert that DB order is preserved */
321 1 : assert_string_equal(msg->elements[0].name, "bar");
322 1 : assert_int_equal(msg->elements[0].num_values, 1);
323 1 : assert_int_equal(msg->elements[0].values[0].length,
324 : strlen(value2));
325 1 : assert_memory_equal(msg->elements[0].values[0].data,
326 : value2, strlen(value2));
327 1 : }
328 :
329 : /*
330 : * Test against a record with two attributes, both matching the one
331 : * specified attribute in the list (a corrupt record)
332 : */
333 1 : static void test_filter_attrs_in_place_two_dup_attr_matched_one_attr(void **state)
334 : {
335 1 : struct ldbtest_ctx *ctx = *state;
336 1 : int ret;
337 :
338 1 : struct ldb_message *msg = ldb_msg_new(ctx);
339 :
340 1 : const char *attrs[] = {"bar", NULL};
341 :
342 1 : char value1[] = "The value.......end";
343 1 : char value2[] = "The value..MUST.end";
344 1 : struct ldb_val value_1 = {
345 : .data = (uint8_t *)value1,
346 1 : .length = strlen(value1)
347 : };
348 1 : struct ldb_val value_2 = {
349 : .data = (uint8_t *)value2,
350 1 : .length = strlen(value2)
351 : };
352 :
353 1 : struct ldb_message_element elements[] = {
354 : {
355 : .name = "bar",
356 : .num_values = 1,
357 : .values = &value_1
358 : },
359 : {
360 : .name = "bar",
361 : .num_values = 1,
362 : .values = &value_2
363 : }
364 : };
365 :
366 1 : assert_non_null(msg);
367 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
368 1 : msg->num_elements = 2;
369 1 : msg->elements = elements;
370 :
371 1 : assert_non_null(msg->dn);
372 1 : msg_add_dn(msg);
373 :
374 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
375 :
376 : /* Both elements match the filter */
377 1 : assert_int_equal(ret, LDB_SUCCESS);
378 1 : assert_int_equal(msg->num_elements, 2);
379 :
380 1 : assert_non_null(msg->dn);
381 :
382 : /* Assert that DB order is preserved */
383 1 : assert_string_equal(msg->elements[0].name, "bar");
384 1 : assert_int_equal(msg->elements[0].num_values, 1);
385 1 : assert_int_equal(msg->elements[0].values[0].length,
386 : strlen(value1));
387 1 : assert_memory_equal(msg->elements[0].values[0].data,
388 : value1, strlen(value1));
389 :
390 1 : assert_string_equal(msg->elements[1].name, "bar");
391 1 : assert_int_equal(msg->elements[1].num_values, 1);
392 1 : assert_int_equal(msg->elements[1].values[0].length,
393 : strlen(value2));
394 1 : assert_memory_equal(msg->elements[1].values[0].data,
395 : value2, strlen(value2));
396 1 : }
397 :
398 : /*
399 : * Test against a record with two attributes, both matching the one
400 : * specified attribute in the list (a corrupt record)
401 : */
402 1 : static void test_filter_attrs_in_place_two_dup_attr_matched_dup(void **state)
403 : {
404 1 : struct ldbtest_ctx *ctx = *state;
405 1 : int ret;
406 :
407 1 : struct ldb_message *msg = ldb_msg_new(ctx);
408 :
409 1 : const char *attrs[] = {"bar", "bar", NULL};
410 :
411 1 : char value1[] = "The value.......end";
412 1 : char value2[] = "The value..MUST.end";
413 1 : struct ldb_val value_1 = {
414 : .data = (uint8_t *)value1,
415 1 : .length = strlen(value1)
416 : };
417 1 : struct ldb_val value_2 = {
418 : .data = (uint8_t *)value2,
419 1 : .length = strlen(value2)
420 : };
421 :
422 1 : struct ldb_message_element elements[] = {
423 : {
424 : .name = "bar",
425 : .num_values = 1,
426 : .values = &value_1
427 : },
428 : {
429 : .name = "bar",
430 : .num_values = 1,
431 : .values = &value_2
432 : }
433 : };
434 :
435 1 : assert_non_null(msg);
436 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
437 1 : msg->num_elements = 2;
438 1 : msg->elements = elements;
439 :
440 1 : assert_non_null(msg->dn);
441 1 : msg_add_dn(msg);
442 :
443 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
444 :
445 : /* This does not fail the pidgenhole test */
446 1 : assert_int_equal(ret, LDB_SUCCESS);
447 1 : assert_int_equal(msg->num_elements, 2);
448 :
449 : /* Assert that DB order is preserved */
450 1 : assert_string_equal(msg->elements[0].name, "bar");
451 1 : assert_int_equal(msg->elements[0].num_values, 1);
452 1 : assert_int_equal(msg->elements[0].values[0].length,
453 : strlen(value1));
454 1 : assert_memory_equal(msg->elements[0].values[0].data,
455 : value1, strlen(value1));
456 1 : assert_string_equal(msg->elements[1].name, "bar");
457 1 : assert_int_equal(msg->elements[1].num_values, 1);
458 1 : assert_int_equal(msg->elements[1].values[0].length,
459 : strlen(value2));
460 1 : assert_memory_equal(msg->elements[1].values[0].data,
461 : value2, strlen(value2));
462 1 : }
463 :
464 : /*
465 : * Test against a record with two attributes, both matching one of the
466 : * specified attributes in the list (a corrupt record)
467 : */
468 1 : static void test_filter_attrs_in_place_two_dup_attr_matched_one_of_two(void **state)
469 : {
470 1 : struct ldbtest_ctx *ctx = *state;
471 1 : int ret;
472 :
473 1 : struct ldb_message *msg = ldb_msg_new(ctx);
474 :
475 1 : const char *attrs[] = {"bar", "foo", NULL};
476 :
477 1 : char value1[] = "The value.......end";
478 1 : char value2[] = "The value..MUST.end";
479 1 : struct ldb_val value_1 = {
480 : .data = (uint8_t *)value1,
481 1 : .length = strlen(value1)
482 : };
483 1 : struct ldb_val value_2 = {
484 : .data = (uint8_t *)value2,
485 1 : .length = strlen(value2)
486 : };
487 :
488 1 : struct ldb_message_element elements[] = {
489 : {
490 : .name = "bar",
491 : .num_values = 1,
492 : .values = &value_1
493 : },
494 : {
495 : .name = "bar",
496 : .num_values = 1,
497 : .values = &value_2
498 : }
499 : };
500 :
501 1 : assert_non_null(msg);
502 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
503 1 : msg->num_elements = 2;
504 1 : msg->elements = elements;
505 :
506 1 : assert_non_null(msg->dn);
507 1 : msg_add_dn(msg);
508 :
509 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
510 :
511 : /* This does not fail the pidgenhole test */
512 1 : assert_int_equal(ret, LDB_SUCCESS);
513 1 : assert_int_equal(msg->num_elements, 2);
514 :
515 : /* Assert that DB order is preserved */
516 1 : assert_string_equal(msg->elements[0].name, "bar");
517 1 : assert_int_equal(msg->elements[0].num_values, 1);
518 1 : assert_int_equal(msg->elements[0].values[0].length,
519 : strlen(value1));
520 1 : assert_memory_equal(msg->elements[0].values[0].data,
521 : value1, strlen(value1));
522 1 : assert_string_equal(msg->elements[1].name, "bar");
523 1 : assert_int_equal(msg->elements[1].num_values, 1);
524 1 : assert_int_equal(msg->elements[1].values[0].length,
525 : strlen(value2));
526 1 : assert_memory_equal(msg->elements[1].values[0].data,
527 : value2, strlen(value2));
528 1 : }
529 :
530 : /*
531 : * Test against a record with two attributes against * (but not the
532 : * other named attribute) (a corrupt record)
533 : */
534 1 : static void test_filter_attrs_in_place_two_dup_attr_matched_star(void **state)
535 : {
536 1 : struct ldbtest_ctx *ctx = *state;
537 1 : int ret;
538 :
539 1 : struct ldb_message *msg = ldb_msg_new(ctx);
540 :
541 1 : const char *attrs[] = {"*", "foo", NULL};
542 :
543 1 : char value1[] = "The value.......end";
544 1 : char value2[] = "The value..MUST.end";
545 1 : struct ldb_val value_1 = {
546 : .data = (uint8_t *)value1,
547 1 : .length = strlen(value1)
548 : };
549 1 : struct ldb_val value_2 = {
550 : .data = (uint8_t *)value2,
551 1 : .length = strlen(value2)
552 : };
553 :
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 :
567 1 : assert_non_null(msg);
568 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
569 1 : msg->num_elements = 2;
570 1 : msg->elements = elements;
571 :
572 1 : assert_non_null(msg->dn);
573 1 : msg_add_dn(msg);
574 :
575 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
576 :
577 : /* This does not fail the pidgenhole test */
578 1 : assert_int_equal(ret, LDB_SUCCESS);
579 1 : assert_int_equal(msg->num_elements, 3);
580 :
581 : /* Assert that DB order is preserved */
582 1 : assert_string_equal(msg->elements[0].name, "bar");
583 1 : assert_int_equal(msg->elements[0].num_values, 1);
584 1 : assert_int_equal(msg->elements[0].values[0].length,
585 : strlen(value1));
586 1 : assert_memory_equal(msg->elements[0].values[0].data,
587 : value1, strlen(value1));
588 1 : assert_string_equal(msg->elements[1].name, "bar");
589 1 : assert_int_equal(msg->elements[1].num_values, 1);
590 1 : assert_int_equal(msg->elements[1].values[0].length,
591 : strlen(value2));
592 1 : assert_memory_equal(msg->elements[1].values[0].data,
593 : value2, strlen(value2));
594 :
595 1 : assert_non_null(msg->dn);
596 1 : assert_string_equal(ldb_msg_find_attr_as_string(msg,
597 : "distinguishedName",
598 : NULL),
599 : ldb_dn_get_linearized(msg->dn));
600 1 : }
601 :
602 : /*
603 : * Test against a record with only one attribute, matching the * in
604 : * the list
605 : */
606 1 : static void test_filter_attrs_in_place_one_attr_matched_star(void **state)
607 : {
608 1 : struct ldbtest_ctx *ctx = *state;
609 1 : int ret;
610 :
611 1 : struct ldb_message *msg = ldb_msg_new(ctx);
612 :
613 1 : const char *attrs[] = {"*", NULL};
614 :
615 1 : char value[] = "The value.......end";
616 1 : struct ldb_val value_1 = {
617 : .data = (uint8_t *)value,
618 1 : .length = strlen(value)
619 : };
620 1 : struct ldb_message_element element_1 = {
621 : .name = "foo",
622 : .num_values = 1,
623 : .values = &value_1
624 : };
625 :
626 1 : assert_non_null(msg);
627 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
628 1 : msg->num_elements = 1;
629 1 : msg->elements = &element_1;
630 :
631 1 : assert_non_null(msg->dn);
632 1 : msg_add_dn(msg);
633 :
634 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
635 1 : assert_int_equal(ret, LDB_SUCCESS);
636 1 : assert_int_equal(msg->num_elements, 2);
637 :
638 1 : assert_non_null(msg->dn);
639 1 : assert_string_equal(ldb_msg_find_attr_as_string(msg,
640 : "distinguishedName",
641 : NULL),
642 : ldb_dn_get_linearized(msg->dn));
643 1 : assert_string_equal(ldb_msg_find_attr_as_string(msg,
644 : "foo",
645 : NULL),
646 : value);
647 1 : }
648 :
649 : /*
650 : * Test against a record with two attributes, matching the * in
651 : * the list
652 : */
653 1 : static void test_filter_attrs_in_place_two_attr_matched_star(void **state)
654 : {
655 1 : struct ldbtest_ctx *ctx = *state;
656 1 : int ret;
657 :
658 1 : struct ldb_message *msg = ldb_msg_new(ctx);
659 :
660 1 : const char *attrs[] = {"*", NULL};
661 :
662 1 : char value1[] = "The value.......end";
663 1 : char value2[] = "The value..MUST.end";
664 1 : struct ldb_val value_1 = {
665 : .data = (uint8_t *)value1,
666 1 : .length = strlen(value1)
667 : };
668 1 : struct ldb_val value_2 = {
669 : .data = (uint8_t *)value2,
670 1 : .length = strlen(value2)
671 : };
672 1 : struct ldb_message_element elements[] = {
673 : {
674 : .name = "foo",
675 : .num_values = 1,
676 : .values = &value_1
677 : },
678 : {
679 : .name = "bar",
680 : .num_values = 1,
681 : .values = &value_2
682 : }
683 : };
684 :
685 1 : assert_non_null(msg);
686 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
687 1 : msg->num_elements = 2;
688 1 : msg->elements = elements;
689 :
690 1 : assert_non_null(msg->dn);
691 1 : msg_add_dn(msg);
692 :
693 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
694 1 : assert_int_equal(ret, LDB_SUCCESS);
695 1 : assert_int_equal(msg->num_elements, 3);
696 :
697 1 : assert_non_null(msg->dn);
698 1 : assert_string_equal(ldb_msg_find_attr_as_string(msg,
699 : "distinguishedName",
700 : NULL),
701 : ldb_dn_get_linearized(msg->dn));
702 1 : assert_string_equal(ldb_msg_find_attr_as_string(msg,
703 : "foo",
704 : NULL),
705 : value1);
706 1 : assert_string_equal(ldb_msg_find_attr_as_string(msg,
707 : "bar",
708 : NULL),
709 : value2);
710 1 : }
711 :
712 : /*
713 : * Test against a record with only one attribute, matching the * in
714 : * the list, but without the DN being pre-filled. Succeeds, but the
715 : * distinguishedName is not added.
716 : */
717 1 : static void test_filter_attrs_in_place_one_attr_matched_star_no_dn(void **state)
718 : {
719 1 : struct ldbtest_ctx *ctx = *state;
720 1 : int ret;
721 :
722 1 : struct ldb_message *msg = ldb_msg_new(ctx);
723 :
724 1 : const char *attrs[] = {"*", NULL};
725 :
726 1 : char value[] = "The value.......end";
727 1 : struct ldb_val value_1 = {
728 : .data = (uint8_t *)value,
729 1 : .length = strlen(value)
730 : };
731 1 : struct ldb_message_element element_1 = {
732 : .name = "foo",
733 : .num_values = 1,
734 : .values = &value_1
735 : };
736 :
737 1 : assert_non_null(msg);
738 1 : msg->dn = NULL;
739 1 : msg->num_elements = 1;
740 1 : msg->elements = &element_1;
741 :
742 1 : assert_null(msg->dn);
743 :
744 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
745 1 : assert_int_equal(ret, LDB_SUCCESS);
746 1 : assert_int_equal(msg->num_elements, 1);
747 1 : }
748 :
749 : /*
750 : * Test against a record with only one attribute, matching the * in
751 : * the list plus requsesting distinguishedName
752 : */
753 1 : static void test_filter_attrs_in_place_one_attr_matched_star_dn(void **state)
754 : {
755 1 : struct ldbtest_ctx *ctx = *state;
756 1 : int ret;
757 :
758 1 : struct ldb_message *msg = ldb_msg_new(ctx);
759 :
760 1 : const char *attrs[] = {"*", "distinguishedName", NULL};
761 :
762 1 : char value[] = "The value.......end";
763 1 : struct ldb_val value_1 = {
764 : .data = (uint8_t *)value,
765 1 : .length = strlen(value)
766 : };
767 1 : struct ldb_message_element element_1 = {
768 : .name = "foo",
769 : .num_values = 1,
770 : .values = &value_1
771 : };
772 :
773 1 : assert_non_null(msg);
774 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
775 1 : msg->num_elements = 1;
776 1 : msg->elements = &element_1;
777 :
778 1 : assert_non_null(msg->dn);
779 1 : msg_add_dn(msg);
780 :
781 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
782 1 : assert_int_equal(ret, LDB_SUCCESS);
783 1 : assert_int_equal(msg->num_elements, 2);
784 :
785 1 : assert_non_null(msg->dn);
786 :
787 1 : assert_string_equal(ldb_msg_find_attr_as_string(msg,
788 : "distinguishedName",
789 : NULL),
790 : ldb_dn_get_linearized(msg->dn));
791 1 : assert_string_equal(ldb_msg_find_attr_as_string(msg,
792 : "foo",
793 : NULL),
794 : value);
795 1 : }
796 :
797 : /*
798 : * Test against a record with only one attribute, but returning
799 : * distinguishedName from the list (only)
800 : */
801 1 : static void test_filter_attrs_in_place_one_attr_matched_dn(void **state)
802 : {
803 1 : struct ldbtest_ctx *ctx = *state;
804 1 : int ret;
805 :
806 1 : struct ldb_message *msg = ldb_msg_new(ctx);
807 :
808 1 : const char *attrs[] = {"distinguishedName", NULL};
809 :
810 1 : char value[] = "The value.......end";
811 1 : struct ldb_val value_1 = {
812 : .data = (uint8_t *)value,
813 1 : .length = strlen(value)
814 : };
815 1 : struct ldb_message_element element_1 = {
816 : .name = "foo",
817 : .num_values = 1,
818 : .values = &value_1
819 : };
820 :
821 1 : assert_non_null(msg);
822 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
823 1 : msg->num_elements = 1;
824 1 : msg->elements = &element_1;
825 :
826 1 : assert_non_null(msg->dn);
827 1 : msg_add_dn(msg);
828 :
829 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
830 1 : assert_int_equal(ret, LDB_SUCCESS);
831 1 : assert_int_equal(msg->num_elements, 1);
832 :
833 1 : assert_non_null(msg->dn);
834 1 : assert_string_equal(msg->elements[0].name, "distinguishedName");
835 1 : assert_int_equal(msg->elements[0].num_values, 1);
836 1 : assert_string_equal((char *)msg->elements[0].values[0].data,
837 : ldb_dn_get_linearized(msg->dn));
838 1 : }
839 :
840 : /*
841 : * Test against a record with only one attribute, not matching the
842 : * empty attribute list
843 : */
844 1 : static void test_filter_attrs_in_place_one_attr_empty_list(void **state)
845 : {
846 1 : struct ldbtest_ctx *ctx = *state;
847 1 : int ret;
848 :
849 1 : struct ldb_message *msg = ldb_msg_new(ctx);
850 :
851 1 : const char *attrs[] = {NULL};
852 :
853 1 : char value[] = "The value.......end";
854 1 : struct ldb_val value_1 = {
855 : .data = (uint8_t *)value,
856 1 : .length = strlen(value)
857 : };
858 1 : struct ldb_message_element element_1 = {
859 : .name = "foo",
860 : .num_values = 1,
861 : .values = &value_1
862 : };
863 :
864 1 : assert_non_null(msg);
865 1 : msg->dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org");
866 1 : msg->num_elements = 1;
867 1 : msg->elements = &element_1;
868 :
869 1 : assert_non_null(msg->dn);
870 1 : msg_add_dn(msg);
871 :
872 1 : ret = ldb_filter_attrs_in_place(msg, attrs);
873 1 : assert_int_equal(ret, LDB_SUCCESS);
874 1 : assert_int_equal(msg->num_elements, 0);
875 1 : assert_non_null(msg->dn);
876 1 : }
877 :
878 1 : int main(int argc, const char **argv)
879 : {
880 1 : const struct CMUnitTest tests[] = {
881 : cmocka_unit_test_setup_teardown(
882 : test_filter_attrs_in_place_one_attr_matched,
883 : setup,
884 : teardown),
885 : cmocka_unit_test_setup_teardown(
886 : test_filter_attrs_in_place_one_attr_matched_of_many,
887 : setup,
888 : teardown),
889 : cmocka_unit_test_setup_teardown(
890 : test_filter_attrs_in_place_two_attr_matched_attrs,
891 : setup,
892 : teardown),
893 : cmocka_unit_test_setup_teardown(
894 : test_filter_attrs_in_place_two_attr_matched_one_attr,
895 : setup,
896 : teardown),
897 : cmocka_unit_test_setup_teardown(
898 : test_filter_attrs_in_place_two_dup_attr_matched_one_attr,
899 : setup,
900 : teardown),
901 : cmocka_unit_test_setup_teardown(
902 : test_filter_attrs_in_place_two_dup_attr_matched_dup,
903 : setup,
904 : teardown),
905 : cmocka_unit_test_setup_teardown(
906 : test_filter_attrs_in_place_two_dup_attr_matched_one_of_two,
907 : setup,
908 : teardown),
909 : cmocka_unit_test_setup_teardown(
910 : test_filter_attrs_in_place_two_dup_attr_matched_star,
911 : setup,
912 : teardown),
913 : cmocka_unit_test_setup_teardown(
914 : test_filter_attrs_in_place_one_attr_matched_star,
915 : setup,
916 : teardown),
917 : cmocka_unit_test_setup_teardown(
918 : test_filter_attrs_in_place_two_attr_matched_star,
919 : setup,
920 : teardown),
921 : cmocka_unit_test_setup_teardown(
922 : test_filter_attrs_in_place_one_attr_matched_star_no_dn,
923 : setup,
924 : teardown),
925 : cmocka_unit_test_setup_teardown(
926 : test_filter_attrs_in_place_one_attr_matched_star_dn,
927 : setup,
928 : teardown),
929 : cmocka_unit_test_setup_teardown(
930 : test_filter_attrs_in_place_one_attr_matched_dn,
931 : setup,
932 : teardown),
933 : cmocka_unit_test_setup_teardown(
934 : test_filter_attrs_in_place_one_attr_empty_list,
935 : setup,
936 : teardown),
937 : };
938 :
939 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
940 :
941 1 : return cmocka_run_group_tests(tests, NULL, NULL);
942 : }
|