6.0.0-beta1
7/13/25

[#11888] Add possibility for composite RDNs in LDAP
Summary Add possibility for composite RDNs in LDAP
Queue Horde Framework Packages
Queue Version Git master
Type Enhancement
State Resolved
Priority 2. Medium
Owners jan (at) horde (dot) org
Requester horde (at) mbox (dot) tinloaf (dot) de
Created 12/14/2012 (4594 days ago)
Due
Updated 06/13/2014 (4048 days ago)
Assigned
Resolved 06/05/2014 (4056 days ago)
Milestone
Patch Yes

History
06/13/2014 04:20:09 PM Git Commit Comment #20 Reply to this comment
Changes have been made in Git (master):

commit 66d81705b7f562667aaf30771565a7447d42aa16
Author: Jan Schneider <jan@horde.org>
Date:   Fri Jun 13 18:19:31 2014 +0200

     [jan] Fix compatibility with PHP 5.3 (Bug #11888).

  framework/Ldap/lib/Horde/Ldap.php |   40 +++++++++++++++++++++---------------
  framework/Ldap/package.xml        |    2 +
  2 files changed, 25 insertions(+), 17 deletions(-)

http://github.com/horde/horde/commit/66d81705b7f562667aaf30771565a7447d42aa16
06/13/2014 01:59:58 PM horde (at) iotti (dot) biz Comment #19 Reply to this comment
No, same problem. Please note that not only the inner array_map fails, 
but even the outer one ( the array_map( function($attribute) { ... )
06/13/2014 01:49:37 PM Jan Schneider Comment #18 Reply to this comment
Instead of
array_map('self::_quoteRDN', $attribute)
try
array_map(array('Horde_Ldap', '_quoteRDN'), $attribute)
06/13/2014 12:03:28 PM horde (at) iotti (dot) biz Comment #17 Reply to this comment
Sorry I just mispelled a variable name. The ccorrect code that works 
for me is:

     public static function quoteDN($parts)
     {
       $p1 = array();
                   foreach( $parts as $attribute ) {
                     if (is_array($attribute[0])) {
                         $p2 = array();
                         foreach( $attribute as $a ) {
                           $p2[] = self::_quoteRDN($a);
                         }
                         $p1[] = implode( '+', $p2 );
                     } else {
                         $p1[] = self::_quoteRDN($attribute);
                     }
                   }

         return implode(
             ',',
             $p1
         );
     }
06/13/2014 11:59:48 AM horde (at) iotti (dot) biz Comment #16 Reply to this comment
Just to point that I remove the calls to array_map with something 
functionally equivalent. Magically all my problems are solved. In 
particular I switchd from:

     public static function quoteDN($parts)
     {
         return implode(
             ',',
             array_map(
                 function($attribute)
                 {
                     if (is_array($attribute[0])) {
                         return implode(
                             '+',
                             array_map('self::_quoteRDN', $attribute)
                         );
                     } else {
                         return self::_quoteRDN($attribute);
                     }
                 },
                 $parts
             )
         );
     }

to:

     public static function quoteDN($parts)
     {
       $p1 = array();
                   foreach( $parts as $attribute ) {
                     if (is_array($attribute[0])) {
                         $p2 = array();
                         foreach( $attribute as $a ) {
                           $a2[] = self::_quoteRDN($a);
                         }
                         $p1[] = implode( '+', $a2 );
                     } else {
                         $p1[] = self::_quoteRDN($attribute);
                     }
                   }

         return implode(
             ',',
             $p1
         );
     }


06/13/2014 11:14:56 AM horde (at) iotti (dot) biz Comment #15 Reply to this comment
Pls forgive me, but this test thing is completely new to me. After 
some figuring out, I managed to run the tests, and they run fine.

I am almost sure that the reason of the failure when I call 
Horde_Ldap::quoteDN from turba has something to do with that php fatal 
error "Cannot access self:: when no class scope is active in 
/usr/share/pear/Horde/Ldap.php".
It seems that array_map('self::_quoteRDN', $attribute) returns 
nothing, at least with my php, at least when calling from Turba.

I read online that that that php fatal error can have something to do 
with the php version. Mine is php-5.3.3-27 from CentOS.
06/13/2014 10:29:08 AM Jan Schneider Comment #14 Reply to this comment
Cannot reproduce, the additional unit test passes just fine.

Please run the Horde_Ldap unit tests locally.
06/13/2014 10:28:20 AM Git Commit Comment #13 Reply to this comment
Changes have been made in Git (master):

commit 4257ba00f6543a5bc82eea4655653f122cb089ae
Author: Jan Schneider <jan@horde.org>
Date:   Fri Jun 13 12:27:23 2014 +0200

     Add another test for bug #11888.

  framework/Ldap/test/Horde/Ldap/LdapTest.php |   12 ++++++++++++
  1 files changed, 12 insertions(+), 0 deletions(-)

http://github.com/horde/horde/commit/4257ba00f6543a5bc82eea4655653f122cb089ae
06/13/2014 09:07:06 AM horde (at) iotti (dot) biz Comment #12 Reply to this comment
Hi Jan

I am trying your version of the patch, which came in 2.1.0, but when I 
call it from turba (see #11889) it does not work.

I did some testing: in turba/lib/Driver/Ldap.php in _makeRDN() there 
is the call to Horde_Ldap::quoteDN(). Exactly:
return Horde_Ldap::quoteDN(self::_makeRDNhelper($attributes, 
$this->_params['dn']));

It is called with these arguments (the value returned by 
self::_makeRDNhelper($attributes, $this->_params['dn']):

2014-06-13T10:24:14+02:00 DEBUG: Variable information:
array(1) {
   [0]=>
   array(3) {
     [0]=>
     array(2) {
       [0]=>
       string(2) "cn"
       [1]=>
       string(3) "Lux"
     }
     [1]=>
     array(2) {
       [0]=>
       string(2) "sn"
       [1]=>
       string(3) "Ten"
     }
     [2]=>
     array(2) {
       [0]=>
       string(1) "o"
       [1]=>
       string(18) "Ifoa Sede Centrale"
     }
   }
}

Backtrace:
1. Turba_Form_AddContact->execute() /usr/share/horde/turba/add.php:68
2. Turba_Driver->add() /usr/share/horde/turba/lib/Form/AddContact.php:76
3. Turba_Driver_Ldap->_makeKey() /usr/share/horde/turba/lib/Driver.php:880
4. Turba_Driver_Ldap->_makeRDN() 
/usr/share/horde/turba/lib/Driver/Ldap.php:508
5. Horde::debug() /usr/share/horde/turba/lib/Driver/Ldap.php:490


With my version, the result of calling Horde_Ldap::quoteDN is:

2014-06-13T10:22:35+02:00 DEBUG: Variable information:
string(34) "cn=Lux+sn=Ten+o=Acme Sede Centrale"

Backtrace:
1. Turba_Form_AddContact->execute() /usr/share/horde/turba/add.php:68
2. Turba_Driver->add() /usr/share/horde/turba/lib/Form/AddContact.php:76
3. Turba_Driver_Ldap->_makeKey() /usr/share/horde/turba/lib/Driver.php:880
4. Turba_Driver_Ldap->_makeRDN() 
/usr/share/horde/turba/lib/Driver/Ldap.php:508
5. Horde::debug() /usr/share/horde/turba/lib/Driver/Ldap.php:492


With the 2.1.0 version it is empty:

2014-06-13T10:24:14+02:00 DEBUG: Variable information:
string(0) ""

Backtrace:
1. Turba_Form_AddContact->execute() /usr/share/horde/turba/add.php:68
2. Turba_Driver->add() /usr/share/horde/turba/lib/Form/AddContact.php:76
3. Turba_Driver_Ldap->_makeKey() /usr/share/horde/turba/lib/Driver.php:880
4. Turba_Driver_Ldap->_makeRDN() 
/usr/share/horde/turba/lib/Driver/Ldap.php:508
5. Horde::debug() /usr/share/horde/turba/lib/Driver/Ldap.php:492


It seems to me that maybe the problem is that the arguments to 
Horde_Ldap::quoteDN() include only nested arrays (i.e. only the '+' 
linked part, not the trailing ',' linked part), but this is needed by 
the Turba code, which later adds the root dn.


Moreover I made another test, I configured Turba tu use simple, not 
composite DNs so I switched from:
$cfgSources['localldap']['params']['dn'] = array(array('cn', 'sn', 'o'));
to:
$cfgSources['localldap']['params']['dn'] = array('cn', 'sn', 'o');

But this yelds:
PHP Fatal error:  Cannot access self:: when no class scope is active 
in /usr/share/pear/Horde/Ldap.php

Maybe you can help correcting these issues?
If you want, you can pm me at luigi at iotti dot biz to make some 
tests, verify etc.

Thank you
06/05/2014 01:21:10 PM Jan Schneider Comment #11
Assigned to Jan Schneider
State ⇒ Resolved
Reply to this comment
I solved it a bit differently to avoid changing the method signature.
06/05/2014 01:21:00 PM Git Commit Comment #10 Reply to this comment
Changes have been made in Git (master):

commit c0bb5c6472460074b7c22cfd73321abe0cf40038
Author: Jan Schneider <jan@horde.org>
Date:   Thu Jun 5 15:20:23 2014 +0200

     [jan] Support multi-value RDNs in Horde_Ldap::quoteDN() (Request #11888).

  framework/Ldap/lib/Horde/Ldap.php           |   74 ++++++++++++++++++++------
  framework/Ldap/package.xml                  |   16 +++---
  framework/Ldap/test/Horde/Ldap/LdapTest.php |   28 ++++++++++
  3 files changed, 93 insertions(+), 25 deletions(-)

http://github.com/horde/horde/commit/c0bb5c6472460074b7c22cfd73321abe0cf40038
06/04/2014 09:06:21 PM horde (at) iotti (dot) biz Comment #9
New Attachment: Horde-Ldap-11888.nested.array.diff Download
Reply to this comment
I worked out the patch the way you suggested.
This approach is certainly more intuitive, as you said, but on the 
other hand in my opinion it makes less clear how to use this new 
possibility in configuring a turba ldap backend (see ticket #11889
where I put the modified turba patch to work with this one).
Anyway, I really don't have a real preference, or even the deep 
knowledge to choose wisely, between the old version or this one, or 
another modified version. It seems to me that nonetheless it would be 
fine to have multi-valued RDNs support.

P.S. Please revise my patch, I'm not a php expert.

Thank you
06/04/2014 10:36:37 AM Jan Schneider Comment #8 Reply to this comment
This is a very hacky approach. A much more intuitive solution would be 
to provide elements of multi-value RDNs as what they are: multiple 
values. So instead of passing a single attribute-value-pair to build a 
single-value RDN for the DN, pass an array of attribute-value-pairs to 
build a multi-value RDN.

Horde_Ldap::quoteDN(array(
     array(
         array('cn', 'Joe Doe'),
         array('ou', 'Department'),
     ),
     array('dc', 'example'),
     array('dc', 'com'),
))

=> CN=Joe Doe+OU=Department,dc=example,dc=com
06/04/2014 07:33:51 AM horde (at) iotti (dot) biz Comment #7
New Attachment: Horde-Ldap-11888.php.diff Download
Reply to this comment
the modified patch
06/04/2014 07:31:40 AM horde (at) iotti (dot) biz Comment #6 Reply to this comment
I would like to submit a minimally modified patch which, building the 
composite RDN, does not include void attibutes.
For example, say that you have some ldap account made this way:
cn: John
sn: Smith
o: Acme inc
---
cn: Mike
sn: Smith
o: Acme inc
---
cn: John
sn: Smith
o:

In this case, if I use cn+sn+o to build the RDN, I would end up with a 
RDN like cn=John+sn=Smith+o= for the latter contact, which is invalid. 
cn=John+sn=Smith (without o=) would be valid instead. The included 
modified patch does this.
The example should also fit for the old example request by Jan. I use 
composite RDNs to be able to store my accounts in LDAP: the accounts 
would collide if I used only a single attribute for the RDN, be it the 
first name, surname, organization...

I'm using this patch (or older versions which appeared in the ML and 
the web) since Turba 2, so I would like to ask for inclusion in the 
main distribution, together with http://bugs.horde.org/ticket/11889 
which is closely related to this.

Thanks
09/06/2013 07:03:05 PM horde (at) mbox (dot) tinloaf (dot) de Comment #5 Reply to this comment
Oh I'm sorry, I wasn't watching this ticket and only found it now that 
I had to patch it in again... what examples do you want?
Ping?
01/30/2013 02:05:59 PM Jan Schneider Comment #4 Reply to this comment
Ping?
01/07/2013 11:08:27 PM Jan Schneider Comment #3
State ⇒ Feedback
Reply to this comment
Can you please add a test case or at least a few examples?
12/14/2012 06:34:26 PM horde (at) mbox (dot) tinloaf (dot) de Comment #2 Reply to this comment
This is the related Turba ticket:

http://bugs.horde.org/ticket/11889

12/14/2012 06:29:47 PM horde (at) mbox (dot) tinloaf (dot) de Comment #1
Priority ⇒ 2. Medium
State ⇒ New
New Attachment: Ldap.php.diff Download
Patch ⇒ Yes
Milestone ⇒
Queue ⇒ Horde Framework Packages
Summary ⇒ Add possibility for composite RDNs in LDAP
Type ⇒ Enhancement
Reply to this comment
The current version of Horde_Ldap does not allow composite RDNs to be 
created (since lack of support for this in the quoteDN() function. 
Please find attached a patch that fixes this. The new quoteDN() 
function will be fully backwards compatible, with one additional 
feature: If the array passed in contains any '+', it will switch to 
'composite mode', concatenating the following key-value-pairs with '+' 
(thus creating a composite RDN). If any ',' are in the array passed to 
quoteDN, it will switch back to default behaviour and concatenate the 
following key-value-pairs with ','.

I'm using this in Turba and opening a separate ticket for the patch to 
be applied in Turba. I'll post a link to this ticket as soon as I 
opened it.

The file to patch is 'lib/Horde/Ldap.php' from the Horde_Ldap PEAR package.

Saved Queries