+#include "lutil.h"
+
+static int
+ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent,
+ struct berval *bdn );
+
+/*
+ * Quick'n'dirty rewrite of filter in case of error, to deal with
+ * <draft-zeilenga-ldap-t-f>.
+ */
+static int
+ldap_back_munge_filter(
+ Operation *op,
+ struct berval *filter )
+{
+ struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
+
+ char *ptr;
+ int gotit = 0;
+
+ Debug( LDAP_DEBUG_ARGS, "=> ldap_back_munge_filter \"%s\"\n",
+ filter->bv_val, 0, 0 );
+
+ for ( ptr = strstr( filter->bv_val, "(?=" );
+ ptr;
+ ptr = strstr( ptr, "(?=" ) )
+ {
+ static struct berval
+ bv_true = BER_BVC( "(?=true)" ),
+ bv_false = BER_BVC( "(?=false)" ),
+ bv_undefined = BER_BVC( "(?=undefined)" ),
+ bv_t = BER_BVC( "(&)" ),
+ bv_f = BER_BVC( "(|)" ),
+ bv_T = BER_BVC( "(objectClass=*)" ),
+ bv_F = BER_BVC( "(!(objectClass=*))" );
+ struct berval *oldbv = NULL,
+ *newbv = NULL,
+ oldfilter = BER_BVNULL;
+
+ if ( strncmp( ptr, bv_true.bv_val, bv_true.bv_len ) == 0 ) {
+ oldbv = &bv_true;
+ if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) {
+ newbv = &bv_t;
+
+ } else {
+ newbv = &bv_T;
+ }
+
+ } else if ( strncmp( ptr, bv_false.bv_val, bv_false.bv_len ) == 0 )
+ {
+ oldbv = &bv_false;
+ if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) {
+ newbv = &bv_f;
+
+ } else {
+ newbv = &bv_F;
+ }
+
+ } else if ( strncmp( ptr, bv_undefined.bv_val, bv_undefined.bv_len ) == 0 )
+ {
+ oldbv = &bv_undefined;
+ newbv = &bv_F;
+
+ } else {
+ gotit = 0;
+ goto done;
+ }
+
+ oldfilter = *filter;
+ if ( newbv->bv_len > oldbv->bv_len ) {
+ filter->bv_len += newbv->bv_len - oldbv->bv_len;
+ if ( filter->bv_val == op->ors_filterstr.bv_val ) {
+ filter->bv_val = op->o_tmpalloc( filter->bv_len + 1,
+ op->o_tmpmemctx );
+
+ AC_MEMCPY( filter->bv_val, op->ors_filterstr.bv_val,
+ op->ors_filterstr.bv_len + 1 );
+
+ } else {
+ filter->bv_val = op->o_tmprealloc( filter->bv_val,
+ filter->bv_len + 1, op->o_tmpmemctx );
+ }
+
+ ptr = filter->bv_val + ( ptr - oldfilter.bv_val );
+ }
+
+ AC_MEMCPY( &ptr[ newbv->bv_len ],
+ &ptr[ oldbv->bv_len ],
+ oldfilter.bv_len - ( ptr - filter->bv_val ) - oldbv->bv_len + 1 );
+ AC_MEMCPY( ptr, newbv->bv_val, newbv->bv_len );
+
+ ptr += newbv->bv_len;
+ gotit = 1;
+ }
+
+done:;
+ Debug( LDAP_DEBUG_ARGS, "<= ldap_back_munge_filter \"%s\" (%d)\n",
+ filter->bv_val, gotit, 0 );
+
+ return gotit;
+}