ldb 1.3.2 fails some tests

Timur I. Bakeyev timur at freebsd.org
Wed Mar 7 21:13:15 UTC 2018


On 7 March 2018 at 04:55, Garming Sam <garming at catalyst.net.nz> wrote:

> The duplicate syntaxes appears to occur here which triggers in the
> ldb_init.
>
> The flags are set as 0, meaning they are not marked
> LDB_ATTR_FLAG_FROM_DB and so are never unloaded. Because qsort seems to
> trigger a stable-sort, it manages to pick the one without the
> UNIQUE_INDEX. One other thing I notice is the the test sets
> UNIQUE_INDEX, which will by default fallback to OCTET_STRING if
> CASE_INSENSITIVE has not been set, which is why there is also an oid
> difference.
>
> /*
>   setup the attribute handles for well known attributes
> */
> int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
>

My understanding is that this function pre-populate well known attribute
schemas, which is pretty valid by itself. But later we are trying to
redefine "cn" schema with UNIQUE INDEX and instead of replacement of
already existing schema new one is just appended. That happens(for the
failing test at least) in ltdb_attributes_load().

We enter function with:

(gdb) p ldb->schema
$1 = {attribute_handler_override_private = 0x0, attribute_handler_override
= 0x0, num_attributes = 6, attributes = 0x613b20, num_dn_extended_syntax =
0,
  dn_extended_syntax = 0x0, index_handler_override = false,
one_level_indexes = false, GUID_index_attribute = 0x0,
GUID_index_dn_component = 0x0}

where 6 in `num_attributes` are those well known attributes loaded in
`attributes` array.

123             dn = ldb_dn_new(module, ldb, LTDB_ATTRIBUTES);
(gdb)
124             if (dn == NULL) goto failed;
(gdb) p *dn
$2 = {ldb = 0x613a00, special = true, invalid = false, valid_case = false,
linearized = 0x624020 "@ATTRIBUTES", ext_linearized = 0x0, casefold = 0x0,
comp_num = 0,
  components = 0x0, ext_comp_num = 0, ext_components = 0x0}
(gdb) n
126         r = ltdb_search_dn1(module, dn, attrs_msg,
                            LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
                            |LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC
                            |LDB_UNPACK_DATA_FLAG_NO_DN);

157                     const struct ldb_schema_attribute *a =
                                          ldb_schema_attribute_by_name(ldb,

attrs_msg->elements[i].name);

(gdb) p a
13 = (const struct ldb_schema_attribute *) 0x613b20
gdb) p *a.
14 = {name = 0x7ffff77ab572 "cn", flags = 0, syntax = 0x7ffff79b3f60
<ldb_standard_syntaxes+96>}
gdb) p *a->syntax
15 = {name = 0x7ffff77ab794 "1.3.6.1.4.1.1466.115.121.1.15", ldif_read_fn =
0x7ffff779841d <ldb_handler_copy>, ldif_write_fn = 0x7ffff779841d
<ldb_handler_copy>,
 canonicalise_fn = 0x7ffff779849f <ldb_handler_fold>, comparison_fn =
0x7ffff7798a04 <ldb_comparison_fold>, operator_fn = 0x0}

And down the code we call:

(gdb)
192                     s = ldb_standard_syntax_by_name(ldb, syntax);

And get entirely different syntax with different flags as a result:

(gdb) p *s
$18 = {name = 0x7ffff77ab776 "1.3.6.1.4.1.1466.115.121.1.40", ldif_read_fn
= 0x7ffff779841d <ldb_handler_copy>, ldif_write_fn = 0x7ffff779841d
<ldb_handler_copy>,
  canonicalise_fn = 0x7ffff779841d <ldb_handler_copy>, comparison_fn =
0x7ffff779899c <ldb_comparison_binary>, operator_fn = 0x0}

Then we unconditionally call:

(gdb) p attr_flags
$19 = 74
(gdb) l
202
203                     r = ldb_schema_attribute_fill_with_syntax(ldb,
204                                                               attrs,
205
attrs_msg->elements[i].name,
206
attr_flags, s,
207
&attrs[num_loaded_attrs + ldb->schema.num_attributes]);

and voila:

(gdb) p *ldb->schema
$20 = {attribute_handler_override_private = 0x0, attribute_handler_override
= 0x0, num_attributes = 7, attributes = 0x6179d0, num_dn_extended_syntax =
0,
  dn_extended_syntax = 0x0, index_handler_override = false,
one_level_indexes = false, GUID_index_attribute = 0x0,
GUID_index_dn_component = 0x0}

We have 7 instead of 6 `num_attributes` and two "cn" schema definitions.

Later on qsort puts them next to each other, but as FreeBSD qsort is
unstable, it's matter of luck, which "cn" schema gets picked. Well,
definitely different, than
on Linux, hence the failures of the test.


More information about the samba-technical mailing list