#define LDAP_DN_ESCAPE(c) ( (c) == '\\' )
#define LDAP_DN_VALUE_END(c) \
( LDAP_DN_RDN_SEP(c) || LDAP_DN_AVA_SEP(c) )
+
+/* NOTE: according to draft-ietf-ldapbis-dn, '=' can be escaped
+ * and treated as special, i.e. escaped both as "\<hexpair>" and
+ * as "\=", but it is treated as a regular char, i.e. it can also
+ * appear as '='.
+ *
+ * As such, we currently choose to allow reading unescaped '=',
+ * but we always produce escaped '\3D'; this may change in the
+ * future, if compatibility issues do not arise */
+#ifdef LDAP_DEVEL
+#define LDAP_DN_NE(c) \
+ ( LDAP_DN_RDN_SEP_V2(c) || LDAP_DN_AVA_SEP(c) \
+ || LDAP_DN_QUOTES(c) \
+ || (c) == '<' || (c) == '>' )
+#define LDAP_DN_MAYESCAPE(c) \
+ ( LDAP_DN_ESCAPE(c) || LDAP_DN_NE(c) \
+ || LDAP_DN_AVA_EQUALS(c) \
+ || LDAP_DN_ASCII_SPACE(c) || LDAP_DN_OCTOTHORPE(c) )
+#define LDAP_DN_SHOULDESCAPE(c) ( LDAP_DN_AVA_EQUALS(c) )
+#else /* ! LDAP_DEVEL */
#define LDAP_DN_NE(c) \
( LDAP_DN_RDN_SEP_V2(c) || LDAP_DN_AVA_SEP(c) \
|| LDAP_DN_AVA_EQUALS(c) || LDAP_DN_QUOTES(c) \
#define LDAP_DN_MAYESCAPE(c) \
( LDAP_DN_ESCAPE(c) || LDAP_DN_NE(c) \
|| LDAP_DN_ASCII_SPACE(c) || LDAP_DN_OCTOTHORPE(c) )
+#define LDAP_DN_SHOULDESCAPE(c) ( 0 )
+#endif /* ! LDAP_DEVEL */
+
#define LDAP_DN_NEEDESCAPE(c) \
( LDAP_DN_ESCAPE(c) || LDAP_DN_NE(c) )
#define LDAP_DN_NEEDESCAPE_LEAD(c) LDAP_DN_MAYESCAPE(c)
*/
return( 1 );
- } else if (!LDAP_DN_ASCII_PRINTABLE( p[ 0 ] ) ) {
+ } else if ( !LDAP_DN_ASCII_PRINTABLE( p[ 0 ] ) ) {
if ( p[ 0 ] == '\0' ) {
return( 1 );
}
l += escaped_byte_len * cl;
} else if ( LDAP_DN_NEEDESCAPE( p[ 0 ] )
+ || LDAP_DN_SHOULDESCAPE( p[ 0 ] )
|| ( p == val->bv_val && LDAP_DN_NEEDESCAPE_LEAD( p[ 0 ] ) )
|| ( !p[ 1 ] && LDAP_DN_NEEDESCAPE_TRAIL( p[ 0 ] ) ) ) {
#ifdef PRETTY_ESCAPE
#endif
#else /* ! PRETTY_ESCAPE */
|| LDAP_DN_NEEDESCAPE( val->bv_val[ s ] )
+ || LDAP_DN_SHOULDESCAPE( val->bv_val[ s ] )
|| ( d == 0 && LDAP_DN_NEEDESCAPE_LEAD( val->bv_val[ s ] ) )
|| ( s == end && LDAP_DN_NEEDESCAPE_TRAIL( val->bv_val[ s ] ) )
} else {
#ifdef PRETTY_ESCAPE
if ( LDAP_DN_NEEDESCAPE( val->bv_val[ s ] )
+ || LDAP_DN_SHOULDESCAPE( val->bv_val[ s ] )
|| ( d == 0 && LDAP_DN_NEEDESCAPE_LEAD( val->bv_val[ s ] ) )
|| ( s == end && LDAP_DN_NEEDESCAPE_TRAIL( val->bv_val[ s ] ) ) ) {
str[ d++ ] = '\\';
} else {
for ( l = 0, p = val->bv_val; p[ 0 ]; p++ ) {
if ( LDAP_DN_NEEDESCAPE( p[ 0 ] )
+ || LDAP_DN_SHOULDESCAPE( p[ 0 ] )
|| ( p == val->bv_val && LDAP_DN_NEEDESCAPE_LEAD( p[ 0 ] ) )
|| ( !p[ 1 ] && LDAP_DN_NEEDESCAPE_TRAIL( p[ 0 ] ) ) ) {
l += 2;
for ( s = 0, d = 0, end = val->bv_len - 1; s < val->bv_len; ) {
if ( LDAP_DN_NEEDESCAPE( val->bv_val[ s ] )
+ || LDAP_DN_SHOULDESCAPE( val->bv_val[ s ] )
|| ( s == 0 && LDAP_DN_NEEDESCAPE_LEAD( val->bv_val[ s ] ) )
|| ( s == end && LDAP_DN_NEEDESCAPE_TRAIL( val->bv_val[ s ] ) ) ) {
str[ d++ ] = '\\';
description: CN=\#John Smith\ ,DC=example,DC=net
description: CN=Lu\C4\8Di\C4\87
+dn: cn=Unescaped Equals,ou=LDAPv3,dc=example,dc=com
+objectClass: groupOfNames
+cn: Unescaped Equals
+member: cn=Unescaped Equals,ou=LDAPv3,dc=example,dc=com
+member: cn=A*x\3Db is a linear algebra problem,ou=LDAPv3,dc=example,dc=com
+description: cn=A*x=b is a linear algebra problem,ou=LDAPv3,dc=example,dc=com
+ // unescaped EQUALS
+
dn: ou=LDAPv2,dc=example,dc=com
objectClass: organizationalUnit
ou: LDAPv2
description: 1.3.6.1.4.1.1466.0=#04024869,DC=example,DC=com
description: 1.1.1=
+dn: cn=Unescaped Equals,ou=LDAPv3,dc=example,dc=com
+objectClass: groupOfNames
+cn: Unescaped Equals
+member: cn=Unescaped Equals,ou=LDAPv3,dc=example,dc=com
+member: cn=A*x=b is a linear algebra problem,ou=LDAPv3,dc=example,dc=com
+description: cn=A*x=b is a linear algebra problem,ou=LDAPv3,dc=example,dc=com // unescaped EQUALS
+
dn: cn=Must Fail 1,ou=Groups,dc=example,dc=com
objectClass: groupOfNames
cn: Must Fail 1