LDAP: Fix separator for multiple attrs and ldapm
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Sun, 29 Nov 2015 00:51:13 +0000 (01:51 +0100)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Sun, 29 Nov 2015 12:59:39 +0000 (13:59 +0100)
Schema:
    attributetype ( NAME foo … )
    attributetype ( NAME foo1 SUP foo …)
    attributetype ( NAME foo2 SUP foo …)

Objects in Directory:
    dn: …
    foo1: foo, bar
    foo1: baz
    foo2: buz

Query and response:
    ldap://<HOST>/<BASE>?foo1?sub?<filter>
    -> foo,, bar,baz

    ldap://<HOST>/<BASE>?foo2?sub?<filter>
    -> buz

    ldap://<HOST>/<BASE>?foo1,foo2?sub?<filter>
    -> foo1="foo,, bar,baz" foo2="buz"

    ldap://<HOST>/<BASE>?foo?sub?<filter>
    -> foo,, bar,baz,buz

The same holds for ldam, but with multiple lines, for each
object one single line.

src/src/lookups/ldap.c

index cfd384c..fe67e7f 100644 (file)
@@ -713,10 +713,15 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
         LDAP_RES_SEARCH_ENTRY)
   {
   LDAPMessage  *e;
         LDAP_RES_SEARCH_ENTRY)
   {
   LDAPMessage  *e;
+  int valuecount;   /* We can see an attr spread across several
+                    entries. If B is derived from A and we request
+                    A and the directory contains both, A and B,
+                    then we get two entries, one for A and one for B.
+                    Here we just count the values per entry */
 
   DEBUG(D_lookup) debug_printf("LDAP result loop\n");
 
 
   DEBUG(D_lookup) debug_printf("LDAP result loop\n");
 
-  for(e = ldap_first_entry(lcp->ld, result);
+  for(e = ldap_first_entry(lcp->ld, result), valuecount = 0;
       e != NULL;
       e = ldap_next_entry(lcp->ld, e))
     {
       e != NULL;
       e = ldap_next_entry(lcp->ld, e))
     {
@@ -775,6 +780,11 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
               attr = US ldap_next_attribute(lcp->ld, e, ber))
       {
       DEBUG(D_lookup) debug_printf("LDAP attr loop\n");
               attr = US ldap_next_attribute(lcp->ld, e, ber))
       {
       DEBUG(D_lookup) debug_printf("LDAP attr loop\n");
+
+      /* In case of attrs_requested == 1 we just count the values, in all other cases
+      (0, >1) we count the values per attribute */
+      if (attrs_requested != 1) valuecount = 0;
+
       if (attr[0] != 0)
         {
         /* Get array of values for this attribute. */
       if (attr[0] != 0)
         {
         /* Get array of values for this attribute. */
@@ -797,6 +807,7 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
             {
             uschar *value = *values;
             int len = Ustrlen(value);
             {
             uschar *value = *values;
             int len = Ustrlen(value);
+            ++valuecount;
 
             DEBUG(D_lookup) debug_printf("LDAP value loop %s:%s\n", attr, value);
 
 
             DEBUG(D_lookup) debug_printf("LDAP value loop %s:%s\n", attr, value);
 
@@ -806,7 +817,7 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
             then query for A.) In all other cases we detect the different
             attribute and append only every non first value. */
 
             then query for A.) In all other cases we detect the different
             attribute and append only every non first value. */
 
-           if ((attr_count == 1 && data) || (values != firstval))
+            if (data && valuecount > 1)
               data = string_cat(data, &size, &ptr, US",", 1);
 
             /* For multiple attributes, the data is in quotes. We must escape
               data = string_cat(data, &size, &ptr, US",", 1);
 
             /* For multiple attributes, the data is in quotes. We must escape