3cf2490 ipaldap: avoid invalid modlist when attribute encoding differs

1 file Authored by ftweedal 3 years ago, Committed by cheimes 3 years ago,
    ipaldap: avoid invalid modlist when attribute encoding differs
    
    ipaldap does not take into account the possibility of the attribute
    encoding returned by python-ldap differing from the attribute
    encoding produced by FreeIPA.  In particular this can occur with DNs
    with special characters that require escaping.  For example,
    python-ldap (or the underlying LDAP library) escapes special
    characters using hex encoding:
    
      CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\2C Inc.,L=Brisbane,C=AU
    
    Whereas FreeIPA, when encoding the DN, escapes the character
    directly:
    
      CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\, Inc.,L=Brisbane,C=AU
    
    Therefore it is possible to generate an invalid modlist. For
    example, during external CA certificate renewal, if the issuer DN
    includes a comma in one of the attribute values (as above), an
    invalid modlist will be generated:
    
      [ (ldap.MOD_ADD, 'ipacaissuerdn',
          [b'CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\, Inc.,L=Brisbane,C=AU'])
      , (ldap.MOD_DELETE, 'ipacaissuerdn',
          [b'CN=Test Sub-CA 201604041620,OU=ftweedal,O=Red Hat\2C Inc.,L=Brisbane,C=AU'])
      ]
    
    Although encoded differently, these are the same value.  If this
    modification is applied to the object, attributeOrValueExists (error
    20) occurs.
    
    To avoid the issue, put deletes before adds in the modlist.  If a
    value is present (with different encodings) as both an addition and
    a deletion, it must be because the original object contained the
    value with a different encoding.  Therefore it is safe to delete it,
    then add it back.
    
    Note that the modlist is not optimal.  In the simplest case (like
    above example), there should be no modification to perform.  It is
    considerably more complex (and more computation) to implement this
    because the raw attribute values must be decoded before comparison.
    
    Fixes: https://pagure.io/freeipa/issue/7750
    Reviewed-By: Christian Heimes <cheimes@redhat.com>
    
        
file modified
+5 -2