LCOV - code coverage report
Current view: top level - lib/ldb/tests - ldb_filter_attrs_test.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 342 342 100.0 %
Date: 2024-04-21 15:09:00 Functions: 17 17 100.0 %

          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             : }

Generated by: LCOV version 1.14