Hi Clément,

sadly we do have the problem that we do not know how many ou= elements are 
present in the DN as the source LDAP is not under our control. Also, the 
structure we currently see is very deep already and would thus cause us to have 
too many tasks.

I would like to propose fixing this problem in a different way. I think the 
issue occurs because RFC 2253, which is about the DN structure, is not specific 
enough. It allows both, just using a backslash to escape certain values but 
also allows these characters to be put into a hex-representation (which is what 
is happening for us). On top of that it, it even allows implementations to 
quote additional characters. So to alleviate this problem and any further 
problems with escaping in the DN, I would modify LSC to maintain a canonic, 
more strict internal representation of DNs. This is fairly easy to achieve as 
the DNs of all incoming search results need only be passed through one method 
and can then pass through LSC without further modifications (as they will still 
be RFC 2253 compliant, just more strictly escaped). In particular, LSC would no 
longer have a comma in a RDN escaped as both \, or \2C but unify this to always 
be \,. 

I wrote and tested a bit of code that relies on Java’s implementation of RFC 
2253, which should be sufficiently strict. This method could be, for example, 
put into org.lsc.utils.StringUtils:

    /**
     * This method will make sure that all DNs from sources and destinations 
are escaped similarly. RFC 2253 is too vague
     * and lets implementations escape either with a simple \ or by also 
converting the character in question into a hex representation.
     * This can cause syncs between differently escaping LDAPs to fail. This 
method should be applied to all results that have been 
     * fetched from the server.
     * 
     * The method will first unescape all RDNs in the DN and the re-escape 
everything using the constructor of javax.naming.ldap.Rdn.
     * 
     * @param dn The DN to canonify.
     * @return The DN in a commonly escaped format.
     * @throws InvalidNameException thrown if the passed DN is not a valid name 
(i.e. the constructor of javax.naming.ldap.LdapName throws this exception).
     */
    public static String canonifyDN(String dn) throws InvalidNameException{
        LdapName name = new LdapName(dn);
        List<Rdn> canonicRdns = new ArrayList<Rdn>();
        for(Rdn rdn : name.getRdns()){
                if(rdn.getValue() instanceof String)
                        canonicRdns.add(new Rdn(rdn.getType(), 
Rdn.unescapeValue((String)rdn.getValue())));
                else
                        //in case this part is not a string we just keep it.
                        canonicRdns.add(rdn);
        }
        return new LdapName(canonicRdns).toString();
    }

You would then add calls to this method in JndiServices.doGetAttrsList(), 
JndiServices.doGetDnList(), as well as LscBean.getInstance() whenever a DN is 
retrieved from a javax.naming object into a LSC-specific data structure.

How does that sound? Any feedback is welcome. We need a solution to this 
problem as soon as possible. 

Best,
Marian


> 2014-12-12 23:54 GMT+01:00 Benjamin Henne <henne at dcsec.uni-hannover.de>:
> >
> > Hi,
> >
> > we have tried to implement what you mention in your link. However, the
> > problems seems to persist. Here's the new mainIdentifier construction:
> >
> > <mainIdentifier>var pos = srcBean.getMainIdentifier().indexOf(",OU=");
> >                         var cn = srcBean.getMainIdentifier().
> > substring(0,pos).split("=")[1];
> >                         var restDN = srcBean.getMainIdentifier().
> > substring(pos);
> >                         restDN = restDN.replace(",DC=de",",c=de");
> >                         var res = "cn="+javax.naming.ldap.Rdn.
> > escapeValue(cn)+restDN;
> >                         res</mainIdentifier>
> >
> >
> > The first sync works fine. But when starting the second the error that
> > occurs is as follows:
> >
> > Dez 12 13:37:39 - ERROR - Error while synchronizing ID cn=Lastname\\,
> > Firstname,ou=Benutzer,c=de: java.lang.RuntimeException:
> > org.apache.directory.api.ldap.model.exception.LdapInvalidDnException:
> > expecting EQUALS, found ','
> > # Fri Dec 12 13:37:39 CET 2014
> > dn: cn=Lastname\\, Firstname,ou=Benutzer,c=de
> > changetype: modrdn
> > newrdn: cn=Lastname\, Firstname
> > deleteoldrdn: 1
> > newsuperior: OU=Benutzer,c=de
> >
> > So LSC continues to stack the escapes. When I look at the debugger for the
> > above statement, the "res" variable contains the correct string every time
> > (both first and consecutive syncs). However, during the second sync, the
> > dstBean variable contains exactly this double-escaped version that is also
> > seen in the above error message. Thus, I think the problem is not in the
> > construction of the MainIdentifier of the srcBean, but in reading the main
> > identifier of the dstBean from OpenLDAP (which is not configurable as far
> > as I understand it). As I wrote in my first post, AD and OpenLDAP seem to
> > encode this differently and therefore LSC finds a DN mismatch. Any help is
> > greatly appreciated.
> >
> >
> 
> The problem may be in getMainIdentifier method.
> 
> If you don't have to many 'ou' (like ou=Benutzer), I think the best would
> be to have a different task per ou, and to have this expression for
> MainIdentifier:
> 
> <mainIdentifier>
> "cn="+javax.naming.ldap.Rdn.escapeValue(srcBean.getDatasetFirstValueById(cn))+",ou=Benutzer,c=de"</mainIdentifier>
> 
> 
> Clément.
> 
> 

-- 
Marian Harbach
Research Associate
Distributed Computing and Security Group
Leibniz Universität Hannover
Schloßwender Str. 5, 30159 Hannover, Germany
Tel. +49 (0) 511 762 79 9038

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________________________
Ldap Synchronization Connector (LSC) - http://lsc-project.org

lsc-users mailing list
[email protected]
http://lists.lsc-project.org/listinfo/lsc-users

Reply via email to