]> git.sur5r.net Git - openldap/commitdiff
First round of imports from HEAD
authorKurt Zeilenga <kurt@openldap.org>
Sun, 9 Feb 2003 17:31:35 +0000 (17:31 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Sun, 9 Feb 2003 17:31:35 +0000 (17:31 +0000)
117 files changed:
configure.in
doc/man/man5/slapd.access.5
doc/man/man5/slapd.conf.5
include/portable.h.in
servers/slapd/Makefile.in
servers/slapd/abandon.c
servers/slapd/acl.c
servers/slapd/aclparse.c
servers/slapd/ad.c
servers/slapd/add.c
servers/slapd/at.c
servers/slapd/back-bdb/Makefile.in
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/attr.c
servers/slapd/back-bdb/attribute.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/bind.c
servers/slapd/back-bdb/cache.c
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/external.h
servers/slapd/back-bdb/filterindex.c
servers/slapd/back-bdb/group.c
servers/slapd/back-bdb/id2entry.c
servers/slapd/back-bdb/idl.c
servers/slapd/back-bdb/index.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/lcup.c [deleted file]
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/operational.c
servers/slapd/back-bdb/passwd.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/psearch.c [new file with mode: 0644]
servers/slapd/back-bdb/search.c
servers/slapd/back-ldap/add.c
servers/slapd/back-ldap/attribute.c [new file with mode: 0644]
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/compare.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/group.c
servers/slapd/back-ldap/init.c
servers/slapd/back-ldap/map.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/search.c
servers/slapd/back-ldap/unbind.c
servers/slapd/back-ldbm/attr.c
servers/slapd/back-ldbm/bind.c
servers/slapd/back-ldbm/cache.c
servers/slapd/back-ldbm/dbcache.c
servers/slapd/back-ldbm/external.h
servers/slapd/back-ldbm/filterindex.c
servers/slapd/back-ldbm/idl.c
servers/slapd/back-ldbm/index.c
servers/slapd/back-ldbm/init.c
servers/slapd/back-ldbm/modify.c
servers/slapd/back-ldbm/proto-back-ldbm.h
servers/slapd/back-meta/add.c
servers/slapd/back-meta/attribute.c [new file with mode: 0644]
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/compare.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/group.c
servers/slapd/back-meta/init.c
servers/slapd/back-meta/modify.c
servers/slapd/back-meta/search.c
servers/slapd/back-monitor/database.c
servers/slapd/back-perl/README [new file with mode: 0644]
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/schema-map.c
servers/slapd/back-sql/search.c
servers/slapd/back-sql/sql-wrap.c
servers/slapd/backend.c
servers/slapd/backglue.c
servers/slapd/bind.c
servers/slapd/cancel.c [new file with mode: 0644]
servers/slapd/compare.c
servers/slapd/config.c
servers/slapd/connection.c
servers/slapd/controls.c
servers/slapd/cr.c
servers/slapd/daemon.c
servers/slapd/delete.c
servers/slapd/entry.c
servers/slapd/extended.c
servers/slapd/filter.c
servers/slapd/filterentry.c
servers/slapd/index.c [new file with mode: 0644]
servers/slapd/init.c
servers/slapd/limits.c
servers/slapd/main.c
servers/slapd/matchedValues.c
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/mods.c
servers/slapd/module.c
servers/slapd/mr.c
servers/slapd/oc.c
servers/slapd/oidm.c
servers/slapd/operation.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/root_dse.c
servers/slapd/sasl.c
servers/slapd/saslauthz.c
servers/slapd/schema_check.c
servers/slapd/schema_init.c
servers/slapd/schema_prep.c
servers/slapd/search.c
servers/slapd/sets.h [new file with mode: 0644]
servers/slapd/slap.h
servers/slapd/syntax.c
servers/slapd/tools/Makefile.in
servers/slapd/tools/mimic.c
servers/slapd/tools/slapcommon.c

index 27881b66f8757ef1be1c4a6dd1ead620ec3c1807..96bc4dab2045f197f44369c1c82274ad0270b3c2 100644 (file)
@@ -632,7 +632,7 @@ AC_LIBTOOL_DLOPEN
 AC_PROG_LIBTOOL
 
 LTSTATIC=""
-if test -z "$LTDYNAMIC" -a "${OPENLDAP_CVS}"; then
+if test -z "$LTDYNAMIC"; then
        LTSTATIC="-static"
 fi
 AC_SUBST(LTSTATIC)dnl
index c889bcc332ce3799f5a774464ff58b57dfecc64e..0ef8ab6e7bb2c25e522ba29ffac3b6f582f7c7d8 100644 (file)
@@ -266,6 +266,12 @@ pattern, or its trailing part, after a
 exactly matches the 
 .BR domain
 pattern.
+The
+.B domain
+of the contacting host is determined by performing a DNS reverse lookup.
+As this lookup can easily be spoofed, use of the
+.B domain
+statement is strongly discouraged.  By default, reverse lookups are disabled.
 .LP
 The statement
 .B set=<pattern>
index 80de15be08d6d934a9019e0e5e34d344d63ce7f1..dba57ff642244a37c8236184ddde511d2fbba705 100644 (file)
@@ -520,8 +520,8 @@ may be used to require no conditions (useful for clearly globally
 set conditions within a particular database).
 .TP
 .B reverse-lookup on | off
-Enable/disable client name reverse lookup (default is 
-.BR on 
+Enable/disable client name unverified reverse lookup (default is 
+.BR off 
 if compiled with --enable-rlookups).
 .TP
 .B rootDSE <file>
index 7efd54231b3bafbacbd0c392929c5e009178d3a6..4cd1077cd309df79ec1bcf4b29d2e15e73d88d20 100644 (file)
 /* Define if you have the getpassphrase function.  */
 #undef HAVE_GETPASSPHRASE
 
+/* Define if you have the getpeereid function.  */
+#undef HAVE_GETPEEREID
+
 /* Define if you have the getpwnam function.  */
 #undef HAVE_GETPWNAM
 
 /* Define if you have the send function.  */
 #undef HAVE_SEND
 
+/* Define if you have the sendmsg function.  */
+#undef HAVE_SENDMSG
+
 /* Define if you have the sendto function.  */
 #undef HAVE_SENDTO
 
 /* Define if you have the <sys/types.h> header file.  */
 #undef HAVE_SYS_TYPES_H
 
+/* Define if you have the <sys/ucred.h> header file.  */
+#undef HAVE_SYS_UCRED_H
+
 /* Define if you have the <sys/un.h> header file.  */
 #undef HAVE_SYS_UN_H
 
 /* define to support LAN Manager passwords */
 #undef SLAPD_LMHASH
 
-/* set to the number of arguments ctime_r() expects */
-#undef CTIME_R_NARGS
-
-/* set to the number of arguments gethostbyname_r() expects */
-#undef GETHOSTBYNAME_R_NARGS
-
-/* set to the number of arguments gethostbyaddr_r() expects */
-#undef GETHOSTBYADDR_R_NARGS
-
 /* if you have NT Threads */
 #undef HAVE_NT_THREADS
 
 /* define if you have (or want) no threads */
 #undef NO_THREADS
 
+/* set to the number of arguments ctime_r() expects */
+#undef CTIME_R_NARGS
+
+/* set to the number of arguments gethostbyname_r() expects */
+#undef GETHOSTBYNAME_R_NARGS
+
+/* set to the number of arguments gethostbyaddr_r() expects */
+#undef GETHOSTBYADDR_R_NARGS
+
 /* define if Berkeley DB has DB_THREAD support */
 #undef HAVE_BERKELEY_DB_THREAD
 
 /* define this to add syslog code */
 #undef LDAP_SYSLOG
 
-/* define this to remove -lldap cache support */
-#undef LDAP_NOCACHE
-
 /* define this for LDAP process title support */
 #undef LDAP_PROCTITLE
 
index 717b91dc7050bdc08269440676b9e01c0c938937..e3e1ae3e56096bbac01d210fe0a23268d6d4ebe0 100644 (file)
@@ -19,7 +19,7 @@ SRCS  = main.c daemon.c connection.c search.c filter.c add.c cr.c \
                schemaparse.c ad.c at.c mr.c syntax.c oc.c saslauthz.c \
                oidm.c starttls.c index.c sets.c referral.c \
                root_dse.c sasl.c module.c suffixalias.c mra.c mods.c \
-               limits.c backglue.c operational.c matchedValues.c \
+               limits.c backglue.c operational.c matchedValues.c cancel.c \
                $(@PLAT@_SRCS)
 
 OBJS   = main.o daemon.o connection.o search.o filter.o add.o cr.o \
@@ -32,7 +32,7 @@ OBJS  = main.o daemon.o connection.o search.o filter.o add.o cr.o \
                schemaparse.o ad.o at.o mr.o syntax.o oc.o saslauthz.o \
                oidm.o starttls.o index.o sets.o referral.o \
                root_dse.o sasl.o module.o suffixalias.o mra.o mods.o \
-               limits.o backglue.o operational.o matchedValues.o \
+               limits.o backglue.o operational.o matchedValues.o cancel.o \
                $(@PLAT@_OBJS)
 
 LDAP_INCDIR= ../../include
index 5f2ac082757636ab8c8896da33eeba2fe1ab8976..33bd0ab159e490793c3840178cc5dc5e2f954dfb 100644 (file)
@@ -1,7 +1,7 @@
 /* abandon.c - decode and handle an ldap abandon operation */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -109,7 +109,7 @@ do_abandon(
 
 done:
 
-#if LDAP_CLIENT_UPDATE
+#ifdef LDAP_CLIENT_UPDATE
        for ( i = 0; i < nbackends; i++ ) {
                if ( strncmp( backends[i].be_type, "bdb", 3 ) ) continue;
                if ( bdb_abandon( &backends[i], conn, id ) == LDAP_SUCCESS ) {
index b33a3e921efa49c3b5480ff2d7c044ba5c4a449e..20935cad3d863989b83aeecb664ea5fc80394b5e 100644 (file)
@@ -1,7 +1,7 @@
 /* acl.c - routines to parse and check acl's */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -130,6 +130,9 @@ access_allowed(
        slap_control_t control;
        const char *attr;
        regmatch_t matches[MAXREMATCHES];
+       int        st_same_attr = 0;
+       int        st_initialized = 0;
+       static AccessControlState state_init = ACL_STATE_INIT;
 
        assert( e != NULL );
        assert( desc != NULL );
@@ -139,7 +142,7 @@ access_allowed(
 
        assert( attr != NULL );
 
-       if( state && state->as_recorded ) { 
+       if( state && state->as_recorded && state->as_vd_ad==desc) { 
                if( state->as_recorded & ACL_STATE_RECORDED_NV &&
                        val == NULL )
                {
@@ -150,6 +153,9 @@ access_allowed(
                {
                        return state->as_result;
                }
+               st_same_attr = 1;
+       } if (state) {
+               state->as_vd_ad=desc;
        }
 
 #ifdef NEW_LOGGING
@@ -246,7 +252,7 @@ access_allowed(
        ret = 0;
        control = ACL_BREAK;
 
-       if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD )) {
+       if( st_same_attr ) {
                assert( state->as_vd_acl != NULL );
 
                a = state->as_vd_acl;
@@ -290,6 +296,18 @@ access_allowed(
 #endif
                }
 
+               if (state) {
+                       if (state->as_vi_acl == a && (state->as_recorded & ACL_STATE_RECORDED_NV)) {
+                               Debug( LDAP_DEBUG_ACL, "access_allowed: result from state (%s)\n", attr, 0, 0 );
+                               return state->as_result;
+                       } else if (!st_initialized) {
+                               Debug( LDAP_DEBUG_ACL, "access_allowed: no res from state (%s)\n", attr, 0, 0);
+                           *state = state_init;
+                               state->as_vd_ad=desc;
+                               st_initialized=1;
+                       }
+               }
+
 vd_access:
                control = acl_mask( a, &mask, be, conn, op,
                        e, desc, val, matches, count, state );
@@ -342,6 +360,9 @@ vd_access:
 
 done:
        if( state != NULL ) {
+               /* If not value-dependent, save ACL in case of more attrs */
+               if ( !(state->as_recorded & ACL_STATE_RECORDED_VD) )
+                       state->as_vi_acl = a;
                state->as_recorded |= ACL_STATE_RECORDED;
                state->as_result = ret;
        }
@@ -961,7 +982,16 @@ dn_match_cleanup:;
                }
 
                if ( b->a_set_pat.bv_len != 0 ) {
-                       if (aci_match_set( &b->a_set_pat, be, e, conn, op, 0 ) == 0) {
+                       struct berval bv;
+                       char buf[ACL_BUF_SIZE];
+                       if( b->a_set_style == ACL_STYLE_REGEX ){
+                               bv.bv_len = sizeof(buf) - 1;
+                               bv.bv_val = buf;
+                               string_expand( &bv, &b->a_set_pat, e->e_ndn, matches );
+                       }else{
+                               bv = b->a_set_pat;
+                       }
+                       if (aci_match_set( &bv, be, e, conn, op, 0 ) == 0) {
                                continue;
                        }
                }
@@ -1201,6 +1231,7 @@ acl_check_modlist(
 )
 {
        struct berval *bv;
+       AccessControlState state = ACL_STATE_INIT;
 
        assert( be != NULL );
 
@@ -1255,9 +1286,6 @@ acl_check_modlist(
        }
 
        for ( ; mlist != NULL; mlist = mlist->sml_next ) {
-               static AccessControlState state_init = ACL_STATE_INIT;
-               AccessControlState state;
-
                /*
                 * no-user-modification operational attributes are ignored
                 * by ACL_WRITE checking as any found here are not provided
@@ -1276,8 +1304,6 @@ acl_check_modlist(
                        continue;
                }
 
-               state = state_init;
-
                switch ( mlist->sml_op ) {
                case LDAP_MOD_REPLACE:
                        /*
index d420a0b4c72d5f4c34023b1c6d5d9fe699e99750..e22f3263ec5a715c7550dc5f20dc42c43942534c 100644 (file)
@@ -1,7 +1,7 @@
 /* aclparse.c - routines to parse and check acl's */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -185,7 +185,7 @@ parse_acl(
                                        } else if ( strcasecmp( style, "one" ) == 0 ) {
                                                a->acl_dn_style = ACL_STYLE_ONE;
                                                ber_str2bv( right, 0, 1, &a->acl_dn_pat );
-                                       } else if ( strcasecmp( style, "subtree" ) == 0 ) {
+                                       } else if ( strcasecmp( style, "subtree" ) == 0 || strcasecmp( style, "sub" ) == 0 ) {
                                                a->acl_dn_style = ACL_STYLE_SUBTREE;
                                                ber_str2bv( right, 0, 1, &a->acl_dn_pat );
                                        } else if ( strcasecmp( style, "children" ) == 0 ) {
@@ -307,7 +307,7 @@ parse_acl(
                                        sty = ACL_STYLE_BASE;
                                } else if ( strcasecmp( style, "one" ) == 0 ) {
                                        sty = ACL_STYLE_ONE;
-                               } else if ( strcasecmp( style, "subtree" ) == 0 ) {
+                               } else if ( strcasecmp( style, "subtree" ) == 0 || strcasecmp( style, "sub" ) == 0 ) {
                                        sty = ACL_STYLE_SUBTREE;
                                } else if ( strcasecmp( style, "children" ) == 0 ) {
                                        sty = ACL_STYLE_CHILDREN;
@@ -1282,7 +1282,7 @@ acl_usage( void )
                        "\t[aci=<attrname>]\n"
 #endif
                        "\t[ssf=<n>] [transport_ssf=<n>] [tls_ssf=<n>] [sasl_ssf=<n>]\n"
-               "<dnstyle> ::= regex | base | exact (alias of base) | one | sub | children\n"
+               "<dnstyle> ::= regex | base | exact (alias of base) | one | subtree | children\n"
                "<style> ::= regex | base | exact (alias of base)\n"
                "<groupflags> ::= R\n"
                "<access> ::= [self]{<level>|<priv>}\n"
index 75a55e4769950ff299faca0ed19b0b65c910b3fd..ece6019282ac7133ec0137000b55dca02328519c 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* ad.c - routines for dealing with attribute descriptions */
 #include "ldap_pvt.h"
 #include "slap.h"
 
+typedef struct Attr_option {
+       struct berval name;     /* option name or prefix */
+       int           prefix;   /* NAME is a tag and range prefix */
+} Attr_option;
+
+static Attr_option lang_option = { { sizeof("lang-")-1, "lang-" }, 1 };
+
+/* Options sorted by name, and number of options */
+static Attr_option *options = &lang_option;
+static int option_count = 1;
+
+static Attr_option *ad_find_option_definition( const char *opt, int optlen );
+
 static int ad_keystring(
        struct berval *bv )
 {
@@ -45,18 +58,18 @@ void ad_destroy( AttributeDescription *ad )
        }
 }
 
-/* Is there an AttributeDescription for this type that uses this language? */
-AttributeDescription * ad_find_lang(
+/* Is there an AttributeDescription for this type that uses these tags? */
+AttributeDescription * ad_find_tags(
        AttributeType *type,
-       struct berval *lang )
+       struct berval *tags )
 {
        AttributeDescription *ad;
 
        ldap_pvt_thread_mutex_lock( &type->sat_ad_mutex );
        for (ad = type->sat_ad; ad; ad=ad->ad_next)
        {
-               if (ad->ad_lang.bv_len == lang->bv_len &&
-                       !strcasecmp(ad->ad_lang.bv_val, lang->bv_val))
+               if (ad->ad_tags.bv_len == tags->bv_len &&
+                       !strcasecmp(ad->ad_tags.bv_val, tags->bv_val))
                        break;
        }
        ldap_pvt_thread_mutex_unlock( &type->sat_ad_mutex );
@@ -102,14 +115,14 @@ int slap_bv2ad(
        AttributeDescription desc, *d2;
        char *name, *options;
        char *opt, *next;
-       int nlang;
-       int langlen;
+       int ntags;
+       int tagslen;
 
        /* hardcoded limits for speed */
-#define MAX_LANG_OPTIONS 128
-       struct berval langs[MAX_LANG_OPTIONS+1];
-#define MAX_LANG_LEN 1024
-       char langbuf[MAX_LANG_LEN];
+#define MAX_TAGGING_OPTIONS 128
+       struct berval tags[MAX_TAGGING_OPTIONS+1];
+#define MAX_TAGS_LEN 1024
+       char tagbuf[MAX_TAGS_LEN];
 
        assert( ad != NULL );
        assert( *ad == NULL ); /* temporary */
@@ -147,9 +160,9 @@ int slap_bv2ad(
        /*
         * parse options in place
         */
-       nlang = 0;
-       memset( langs, 0, sizeof( langs ));
-       langlen = 0;
+       ntags = 0;
+       memset( tags, 0, sizeof( tags ));
+       tagslen = 0;
 
        for( opt=options; opt != NULL; opt=next ) {
                int optlen;
@@ -178,17 +191,16 @@ int slap_bv2ad(
                        desc.ad_flags |= SLAP_DESC_BINARY;
                        continue;
 
-               } else if ( optlen >= sizeof("lang-")-1 &&
-                       strncasecmp( opt, "lang-", sizeof("lang-")-1 ) == 0 )
+               } else if ( ad_find_option_definition( opt, optlen ) )
                {
                        int i;
 
                        if( opt[optlen-1] == '-' ) {
-                               desc.ad_flags |= SLAP_DESC_LANG_RANGE;
+                               desc.ad_flags |= SLAP_DESC_TAG_RANGE;
                        }
 
-                       if( nlang >= MAX_LANG_OPTIONS ) {
-                               *text = "too many language options";
+                       if( ntags >= MAX_TAGGING_OPTIONS ) {
+                               *text = "too many tagging options";
                                return rtn;
                        }
 
@@ -196,38 +208,38 @@ int slap_bv2ad(
                         * tags should be presented in sorted order,
                         * so run the array in reverse.
                         */
-                       for( i=nlang-1; i>=0; i-- ) {
+                       for( i=ntags-1; i>=0; i-- ) {
                                int rc;
 
-                               rc = strncasecmp( opt, langs[i].bv_val,
-                                       (unsigned) optlen < langs[i].bv_len
-                                               ? optlen : langs[i].bv_len );
+                               rc = strncasecmp( opt, tags[i].bv_val,
+                                       (unsigned) optlen < tags[i].bv_len
+                                               ? optlen : tags[i].bv_len );
 
-                               if( rc == 0 && (unsigned)optlen == langs[i].bv_len ) {
+                               if( rc == 0 && (unsigned)optlen == tags[i].bv_len ) {
                                        /* duplicate (ignore) */
                                        goto done;
 
                                } else if ( rc > 0 ||
-                                       ( rc == 0 && (unsigned)optlen > langs[i].bv_len ))
+                                       ( rc == 0 && (unsigned)optlen > tags[i].bv_len ))
                                {
-                                       AC_MEMCPY( &langs[i+1], &langs[i],
-                                               (nlang-i)*sizeof(struct berval) );
-                                       langs[i].bv_val = opt;
-                                       langs[i].bv_len = optlen;
+                                       AC_MEMCPY( &tags[i+1], &tags[i],
+                                               (ntags-i)*sizeof(struct berval) );
+                                       tags[i].bv_val = opt;
+                                       tags[i].bv_len = optlen;
                                        goto done;
                                }
                        }
 
-                       if( nlang ) {
-                               AC_MEMCPY( &langs[1], &langs[0],
-                                       nlang*sizeof(struct berval) );
+                       if( ntags ) {
+                               AC_MEMCPY( &tags[1], &tags[0],
+                                       ntags*sizeof(struct berval) );
                        }
-                       langs[0].bv_val = opt;
-                       langs[0].bv_len = optlen;
+                       tags[0].bv_val = opt;
+                       tags[0].bv_len = optlen;
 
 done:;
-                       langlen += optlen + 1;
-                       nlang++;
+                       tagslen += optlen + 1;
+                       ntags++;
 
                } else {
                        *text = "unrecognized option";
@@ -235,27 +247,27 @@ done:;
                }
        }
 
-       if( nlang > 0 ) {
+       if( ntags > 0 ) {
                int i;
 
-               if( langlen > MAX_LANG_LEN ) {
-                       *text = "language options too long";
+               if( tagslen > MAX_TAGS_LEN ) {
+                       *text = "tagging options too long";
                        return rtn;
                }
 
-               desc.ad_lang.bv_val = langbuf;
-               langlen = 0;
+               desc.ad_tags.bv_val = tagbuf;
+               tagslen = 0;
 
-               for( i=0; i<nlang; i++ ) {
-                       AC_MEMCPY( &desc.ad_lang.bv_val[langlen],
-                               langs[i].bv_val, langs[i].bv_len );
+               for( i=0; i<ntags; i++ ) {
+                       AC_MEMCPY( &desc.ad_tags.bv_val[tagslen],
+                               tags[i].bv_val, tags[i].bv_len );
 
-                       langlen += langs[i].bv_len;
-                       desc.ad_lang.bv_val[langlen++] = ';';
+                       tagslen += tags[i].bv_len;
+                       desc.ad_tags.bv_val[tagslen++] = ';';
                }
 
-               desc.ad_lang.bv_val[--langlen] = '\0';
-               desc.ad_lang.bv_len = langlen;
+               desc.ad_tags.bv_val[--tagslen] = '\0';
+               desc.ad_tags.bv_len = tagslen;
        }
 
        /* see if a matching description is already cached */
@@ -263,14 +275,14 @@ done:;
                if( d2->ad_flags != desc.ad_flags ) {
                        continue;
                }
-               if( d2->ad_lang.bv_len != desc.ad_lang.bv_len ) {
+               if( d2->ad_tags.bv_len != desc.ad_tags.bv_len ) {
                        continue;
                }
-               if( d2->ad_lang.bv_len == 0 ) {
+               if( d2->ad_tags.bv_len == 0 ) {
                        break;
                }
-               if( strncasecmp( d2->ad_lang.bv_val, desc.ad_lang.bv_val,
-                       desc.ad_lang.bv_len ) == 0 )
+               if( strncasecmp( d2->ad_tags.bv_val, desc.ad_tags.bv_val,
+                       desc.ad_tags.bv_len ) == 0 )
                {
                        break;
                }
@@ -284,12 +296,12 @@ done:;
                for (d2 = desc.ad_type->sat_ad; d2; d2=d2->ad_next) {
                        if (d2->ad_flags != desc.ad_flags)
                                continue;
-                       if (d2->ad_lang.bv_len != desc.ad_lang.bv_len)
+                       if (d2->ad_tags.bv_len != desc.ad_tags.bv_len)
                                continue;
-                       if (d2->ad_lang.bv_len == 0)
+                       if (d2->ad_tags.bv_len == 0)
                                break;
-                       if (strncasecmp(d2->ad_lang.bv_val, desc.ad_lang.bv_val,
-                               desc.ad_lang.bv_len) == 0)
+                       if (strncasecmp(d2->ad_tags.bv_val, desc.ad_tags.bv_val,
+                               desc.ad_tags.bv_len) == 0)
                                break;
                }
                if (d2) {
@@ -300,44 +312,73 @@ done:;
                /* Allocate a single contiguous block. If there are no
                 * options, we just need space for the AttrDesc structure.
                 * Otherwise, we need to tack on the full name length +
-                * options length.
+                * options length, + maybe tagging options length again.
                 */
-               if (desc.ad_lang.bv_len || desc.ad_flags != SLAP_DESC_NONE) {
-                       dlen = desc.ad_type->sat_cname.bv_len;
-                       if (desc.ad_lang.bv_len) {
-                               dlen += 1+desc.ad_lang.bv_len;
+               if (desc.ad_tags.bv_len || desc.ad_flags != SLAP_DESC_NONE) {
+                       dlen = desc.ad_type->sat_cname.bv_len + 1;
+                       if (desc.ad_tags.bv_len) {
+                               dlen += 1+desc.ad_tags.bv_len;
                        }
                        if( slap_ad_is_binary( &desc ) ) {
-                               dlen += sizeof(";binary")-1;
+                               dlen += sizeof(";binary")+desc.ad_tags.bv_len;
                        }
                }
 
-               d2 = ch_malloc(sizeof(AttributeDescription) + dlen + 1);
+               d2 = ch_malloc(sizeof(AttributeDescription) + dlen);
                d2->ad_type = desc.ad_type;
                d2->ad_flags = desc.ad_flags;
                d2->ad_cname.bv_len = desc.ad_type->sat_cname.bv_len;
-               d2->ad_lang.bv_len = desc.ad_lang.bv_len;
+               d2->ad_tags.bv_len = desc.ad_tags.bv_len;
 
                if (dlen == 0) {
                        d2->ad_cname.bv_val = d2->ad_type->sat_cname.bv_val;
-                       d2->ad_lang.bv_val = NULL;
+                       d2->ad_tags.bv_val = NULL;
                } else {
+                       char *cp, *op, *lp;
+                       int j;
                        d2->ad_cname.bv_val = (char *)(d2+1);
                        strcpy(d2->ad_cname.bv_val, d2->ad_type->sat_cname.bv_val);
+                       cp = d2->ad_cname.bv_val + d2->ad_cname.bv_len;
                        if( slap_ad_is_binary( &desc ) ) {
-                               strcpy(d2->ad_cname.bv_val+d2->ad_cname.bv_len,
-                                       ";binary");
-                               d2->ad_cname.bv_len += sizeof(";binary")-1;
+                               op = cp;
+                               lp = NULL;
+                               if( desc.ad_tags.bv_len ) {
+                                       lp = desc.ad_tags.bv_val;
+                                       while( strncasecmp(lp, "binary", sizeof("binary")-1) < 0
+                                              && (lp = strchr( lp, ';' )) != NULL )
+                                               ++lp;
+                                       if( lp != desc.ad_tags.bv_val ) {
+                                               *cp++ = ';';
+                                               j = (lp
+                                                    ? lp - desc.ad_tags.bv_val - 1
+                                                    : strlen( desc.ad_tags.bv_val ));
+                                               strncpy(cp, desc.ad_tags.bv_val, j);
+                                               cp += j;
+                                       }
+                               }
+                               strcpy(cp, ";binary");
+                               cp += sizeof(";binary")-1;
+                               if( lp != NULL ) {
+                                       *cp++ = ';';
+                                       strcpy(cp, lp);
+                                       cp += strlen( cp );
+                               }
+                               d2->ad_cname.bv_len = cp - d2->ad_cname.bv_val;
+                               if( desc.ad_tags.bv_len )
+                                       ldap_pvt_str2lower(op);
+                               j = 1;
+                       } else {
+                               j = 0;
                        }
-                       if( d2->ad_lang.bv_len ) {
-                               d2->ad_cname.bv_val[d2->ad_cname.bv_len++]=';';
-                               d2->ad_lang.bv_val = d2->ad_cname.bv_val+
-                                       d2->ad_cname.bv_len;
-                               strncpy(d2->ad_lang.bv_val,desc.ad_lang.bv_val,
-                                       d2->ad_lang.bv_len);
-                               d2->ad_lang.bv_val[d2->ad_lang.bv_len] = '\0';
-                               ldap_pvt_str2lower(d2->ad_lang.bv_val);
-                               d2->ad_cname.bv_len += d2->ad_lang.bv_len;
+                       if( desc.ad_tags.bv_len ) {
+                               lp = d2->ad_cname.bv_val + d2->ad_cname.bv_len + j;
+                               if ( j == 0 )
+                                       *lp++ = ';';
+                               d2->ad_tags.bv_val = lp;
+                               strcpy(lp, desc.ad_tags.bv_val);
+                               ldap_pvt_str2lower(lp);
+                               if( j == 0 )
+                                       d2->ad_cname.bv_len += 1 + desc.ad_tags.bv_len;
                        }
                }
                /* Add new desc to list. We always want the bare Desc with
@@ -363,25 +404,25 @@ done:;
        return LDAP_SUCCESS;
 }
 
-static int is_ad_sublang(
-       struct berval *sublangbv, 
-       struct berval *suplangbv )
+static int is_ad_subtags(
+       struct berval *subtagsbv, 
+       struct berval *suptagsbv )
 {
-       const char *suplang, *supp, *supdelimp;
-       const char *sublang, *subp, *subdelimp;
+       const char *suptags, *supp, *supdelimp;
+       const char *subtags, *subp, *subdelimp;
        int  suplen, sublen;
 
-       if( suplangbv->bv_len == 0 ) return 1;
-       if( sublangbv->bv_len == 0 ) return 0;
+       if( suptagsbv->bv_len == 0 ) return 1;
+       if( subtagsbv->bv_len == 0 ) return 0;
 
-       sublang =sublangbv->bv_val;
-       suplang =suplangbv->bv_val;
+       subtags =subtagsbv->bv_val;
+       suptags =suptagsbv->bv_val;
 
-       for( supp=suplang ; supp; supp=supdelimp ) {
+       for( supp=suptags ; supp; supp=supdelimp ) {
                supdelimp = strchrlen( supp, ';', &suplen );
                if( supdelimp ) supdelimp++;
 
-               for( subp=sublang ; subp; subp=subdelimp ) {
+               for( subp=subtags ; subp; subp=subdelimp ) {
                        subdelimp = strchrlen( subp, ';', &sublen );
                        if( subdelimp ) subdelimp++;
 
@@ -413,13 +454,13 @@ int is_ad_subtype(
        }
 
        /* ensure sub does support all flags of super */
-       lr = sub->ad_lang.bv_len ? SLAP_DESC_LANG_RANGE : 0;
+       lr = sub->ad_tags.bv_len ? SLAP_DESC_TAG_RANGE : 0;
        if(( super->ad_flags & ( sub->ad_flags | lr )) != super->ad_flags ) {
                return 0;
        }
 
-       /* check for language tags */
-       if ( !is_ad_sublang( &sub->ad_lang, &super->ad_lang )) {
+       /* check for tagging options */
+       if ( !is_ad_subtags( &sub->ad_tags, &super->ad_tags )) {
                return 0;
        }
 
@@ -562,8 +603,8 @@ int slap_bv2undef_ad(
                        bv->bv_len);
                
                desc->ad_flags = SLAP_DESC_NONE;
-               desc->ad_lang.bv_val = NULL;
-               desc->ad_lang.bv_len = 0;
+               desc->ad_tags.bv_val = NULL;
+               desc->ad_tags.bv_len = 0;
 
                desc->ad_cname.bv_len = bv->bv_len;
                desc->ad_cname.bv_val = (char *)(desc+1);
@@ -702,3 +743,105 @@ str2anlist( AttributeName *an, char *in, const char *brkstr )
        return( an );
 }
 
+
+/* Define an attribute option. */
+int
+ad_define_option( const char *name, const char *fname, int lineno )
+{
+       int i;
+       unsigned int optlen;
+
+       if ( options == &lang_option ) {
+               options = NULL;
+               option_count = 0;
+       }
+       if ( name == NULL )
+               return 0;
+
+       optlen = 0;
+       do {
+               if ( !DESC_CHAR( name[optlen] ) ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONFIG, CRIT,
+                                 "%s: line %d: illegal option name \"%s\"\n",
+                                 fname, lineno, name );
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                              "%s: line %d: illegal option name \"%s\"\n",
+                                   fname, lineno, name );
+#endif
+                       return 1;
+               }
+       } while ( name[++optlen] );
+
+       options = ch_realloc( options,
+               (option_count+1) * sizeof(Attr_option) );
+
+       if ( strcasecmp( name, "binary" ) == 0
+            || ad_find_option_definition( name, optlen ) ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( CONFIG, CRIT,
+                         "%s: line %d: option \"%s\" is already defined\n",
+                         fname, lineno, name );
+#else
+               Debug( LDAP_DEBUG_ANY,
+                      "%s: line %d: option \"%s\" is already defined\n",
+                      fname, lineno, name );
+#endif
+               return 1;
+       }
+
+       for ( i = option_count; i; --i ) {
+               if ( strcasecmp( name, options[i-1].name.bv_val ) >= 0 )
+                       break;
+               options[i] = options[i-1];
+       }
+
+       options[i].name.bv_val = ch_strdup( name );
+       options[i].name.bv_len = optlen;
+       options[i].prefix = (name[optlen-1] == '-');
+
+       if ( i != option_count &&
+            options[i].prefix &&
+            optlen < options[i+1].name.bv_len &&
+            strncasecmp( name, options[i+1].name.bv_val, optlen ) == 0 ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONFIG, CRIT,
+                                 "%s: line %d: option \"%s\" overrides previous option\n",
+                                 fname, lineno, name );
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                              "%s: line %d: option \"%s\" overrides previous option\n",
+                                   fname, lineno, name );
+#endif
+                       return 1;
+       }
+
+       option_count++;
+       return 0;
+}
+
+/* Find the definition of the option name or prefix matching the arguments */
+static Attr_option *
+ad_find_option_definition( const char *opt, int optlen )
+{
+       int top = 0, bot = option_count;
+       while ( top < bot ) {
+               int mid = (top + bot) / 2;
+               int mlen = options[mid].name.bv_len;
+               char *mname = options[mid].name.bv_val;
+               int j;
+               if ( optlen < mlen ) {
+                       j = strncasecmp( opt, mname, optlen ) - 1;
+               } else {
+                       j = strncasecmp( opt, mname, mlen );
+                       if ( j==0 && (optlen==mlen || options[mid].prefix) )
+                               return &options[mid];
+               }
+               if ( j < 0 )
+                       bot = mid;
+               else
+                       top = mid + 1;
+       }
+       return NULL;
+}
index 85e6f7ca50012614f79f411d4612bcf235fa5baa..d0b393d3646b46bafc5c1efb3bc9a3da9b69f83e 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
 #include "ldap_pvt.h"
 #include "slap.h"
 
-static int slap_mods2entry(
-       Modifications *mods,
-       Entry **e,
-       int repl_user,
-       const char **text,
-       char *textbuf, size_t textlen );
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+static Slapi_PBlock *initAddPlugin( Backend *be, Connection *conn, Operation *op,
+       struct berval *dn, Entry *e, int manageDSAit );
+static int doPreAddPluginFNs( Backend *be, Slapi_PBlock *pb );
+static void doPostAddPluginFNs( Backend *be, Slapi_PBlock *pb );
+#endif /* LDAP_SLAPI */
 
 int
 do_add( Connection *conn, Operation *op )
@@ -48,6 +49,9 @@ do_add( Connection *conn, Operation *op )
        const char *text;
        int                     rc = LDAP_SUCCESS;
        int     manageDSAit;
+#ifdef LDAP_SLAPI
+       Slapi_PBlock    *pb = NULL;
+#endif /* LDAP_SLAPI */
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_add: conn %d enter\n", conn->c_connid,0,0 );
@@ -228,6 +232,10 @@ do_add( Connection *conn, Operation *op )
                goto done;
        }
 
+#ifdef LDAP_SLAPI
+       pb = initAddPlugin( be, conn, op, &dn, e, manageDSAit );
+#endif /* LDAP_SLAPI */
+
        /*
         * do the add if 1 && (2 || 3)
         * 1) there is an add function implemented in this backend;
@@ -279,6 +287,18 @@ do_add( Connection *conn, Operation *op )
                                goto done;
                        }
 
+#ifdef LDAP_SLAPI
+                       /*
+                        * Call the preoperation plugin here, because the entry
+                        * will actually contain something.
+                        */
+                       rc = doPreAddPluginFNs( be, pb );
+                       if ( rc != LDAP_SUCCESS ) {
+                               /* plugin will have sent result */
+                               goto done;
+                       }
+#endif /* LDAP_SLAPI */
+
                        if ( (*be->be_add)( be, conn, op, e ) == 0 ) {
 #ifdef SLAPD_MULTIMASTER
                                if ( !repl_user )
@@ -292,18 +312,39 @@ do_add( Connection *conn, Operation *op )
 
 #ifndef SLAPD_MULTIMASTER
                } else {
-                       BerVarray defref = be->be_update_refs
+                       BerVarray defref;
+                       BerVarray ref;
+#ifdef LDAP_SLAPI
+                       /*
+                        * SLAPI_ADD_ENTRY will be empty, but this may be acceptable
+                        * on replicas (for now, it involves the minimum code intrusion).
+                        */
+                       rc = doPreAddPluginFNs( be, pb );
+                       if ( rc != LDAP_SUCCESS ) {
+                               /* plugin will have sent result */
+                               goto done;
+                       }
+#endif /* LDAP_SLAPI */
+
+                       defref = be->be_update_refs
                                ? be->be_update_refs : default_referral;
-                       BerVarray ref = referral_rewrite( defref,
+                       ref = referral_rewrite( defref,
                                NULL, &e->e_name, LDAP_SCOPE_DEFAULT );
 
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL,
                                ref ? ref : defref, NULL );
 
                        if ( ref ) ber_bvarray_free( ref );
-#endif
+#endif /* SLAPD_MULTIMASTER */
                }
        } else {
+#ifdef LDAP_SLAPI
+           rc = doPreAddPluginFNs( be, pb );
+           if ( rc != LDAP_SUCCESS ) {
+               /* plugin will have sent result */
+               goto done;
+           }
+#endif
 #ifdef NEW_LOGGING
            LDAP_LOG( OPERATION, INFO, 
                       "do_add: conn %d  no backend support\n", conn->c_connid, 0, 0 );
@@ -314,6 +355,10 @@ do_add( Connection *conn, Operation *op )
                              NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
+#ifdef LDAP_SLAPI
+       doPostAddPluginFNs( be, pb );
+#endif /* LDAP_SLAPI */
+
 done:
        if( modlist != NULL ) {
                slap_mods_free( modlist );
@@ -325,7 +370,8 @@ done:
        return rc;
 }
 
-static int slap_mods2entry(
+int
+slap_mods2entry(
        Modifications *mods,
        Entry **e,
        int repl_user,
@@ -413,7 +459,7 @@ static int slap_mods2entry(
                                char            textbuf[ SLAP_TEXT_BUFLEN ]  = { '\0' };
                                
                                rc = modify_check_duplicates( mods->sml_desc, mr,
-                                               NULL, mods->sml_bvalues,
+                                               NULL, mods->sml_bvalues, 0,
                                                &text, textbuf, sizeof( textbuf ) );
 
                                if ( rc != LDAP_SUCCESS ) {
@@ -439,3 +485,65 @@ static int slap_mods2entry(
 
        return LDAP_SUCCESS;
 }
+
+#ifdef LDAP_SLAPI
+static Slapi_PBlock *initAddPlugin( Backend *be, Connection *conn, Operation *op,
+       struct berval *dn, Entry *e, int manageDSAit )
+{
+       Slapi_PBlock *pb;
+
+       pb = op->o_pb;
+
+       slapi_x_backend_set_pb( pb, be );
+       slapi_x_connection_set_pb( pb, conn );
+       slapi_x_operation_set_pb( pb, op );
+
+       slapi_pblock_set( pb, SLAPI_ADD_TARGET, (void *)dn->bv_val );
+       slapi_pblock_set( pb, SLAPI_ADD_ENTRY, (void *)e );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+
+       return pb;
+}
+
+static int doPreAddPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+       int rc;
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_ADD_FN, pb );
+       if ( rc != 0 ) {
+               /*
+                * A preoperation plugin failure will abort the
+                * entire operation.
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_add: add preoperation plugin failed\n",
+                               0, 0, 0);
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_add: add preoperation plugin failed.\n",
+                               0, 0, 0);
+               if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0 )
+                       rc = LDAP_OTHER;
+#endif
+       } else {
+               rc = LDAP_SUCCESS;
+       }
+
+       return rc;
+}
+
+static void doPostAddPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+       int rc;
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_POST_ADD_FN, pb );
+       if ( rc != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_add: add postoperation plugin failed\n",
+                               0, 0, 0);
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_add: add preoperation plugin failed.\n",
+                               0, 0, 0);
+#endif
+       }
+}
+#endif /* LDAP_SLAPI */
index 87d174ca9d47f049b6d8ce3b7fbc78d5896ff8bc..395d50b8dd28fc13850a0865edd71d250d1b1347 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* at.c - routines for dealing with attribute types */
@@ -49,14 +49,17 @@ struct aindexrec {
 };
 
 static Avlnode *attr_index = NULL;
-static AttributeType *attr_list = NULL;
+static LDAP_SLIST_HEAD(ATList, slap_attribute_type) attr_list
+       = LDAP_SLIST_HEAD_INITIALIZER(&attr_list);
 
 static int
 attr_index_cmp(
-    struct aindexrec   *air1,
-    struct aindexrec   *air2
+    const void *v_air1,
+    const void *v_air2
 )
 {
+       const struct aindexrec  *air1 = v_air1;
+       const struct aindexrec  *air2 = v_air2;
        int i = air1->air_name.bv_len - air2->air_name.bv_len;
        if (i)
                return i;
@@ -65,10 +68,12 @@ attr_index_cmp(
 
 static int
 attr_index_name_cmp(
-    struct berval      *type,
-    struct aindexrec   *air
+    const void *v_type,
+    const void *v_air
 )
 {
+    const struct berval    *type = v_type;
+    const struct aindexrec *air  = v_air;
        int i = type->bv_len - air->air_name.bv_len;
        if (i)
                return i;
@@ -96,8 +101,7 @@ at_bvfind(
 {
        struct aindexrec *air;
 
-       air = (struct aindexrec *) avl_find( attr_index, name,
-            (AVL_CMP) attr_index_name_cmp );
+       air = avl_find( attr_index, name, attr_index_name_cmp );
 
        return air != NULL ? air->air_at : NULL;
 }
@@ -194,18 +198,22 @@ at_find_in_list(
 void
 at_destroy( void )
 {
-       AttributeType *a, *n;
+       AttributeType *a;
        avl_free(attr_index, ldap_memfree);
 
-       for (a=attr_list; a; a=n) {
-               n = a->sat_next;
+       while( !LDAP_SLIST_EMPTY(&attr_list) ) {
+               a = LDAP_SLIST_FIRST(&attr_list);
+               LDAP_SLIST_REMOVE_HEAD(&attr_list, sat_next);
+
                if (a->sat_subtypes) ldap_memfree(a->sat_subtypes);
                ad_destroy(a->sat_ad);
                ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex);
                ldap_attributetype_free((LDAPAttributeType *)a);
        }
-       if ( slap_schema.si_at_undefined )
+
+       if ( slap_schema.si_at_undefined ) {
                ad_destroy(slap_schema.si_at_undefined->sat_ad);
+       }
 }
 
 int
@@ -213,7 +221,7 @@ at_start( AttributeType **at )
 {
        assert( at );
 
-       *at = attr_list;
+       *at = LDAP_SLIST_FIRST(&attr_list);
 
        return (*at != NULL);
 }
@@ -225,9 +233,9 @@ at_next( AttributeType **at )
 
 #if 1  /* pedantic check */
        {
-               AttributeType *tmp;
+               AttributeType *tmp = NULL;
 
-               for ( tmp = attr_list; tmp; tmp = tmp->sat_next ) {
+               LDAP_SLIST_FOREACH(tmp,&attr_list,sat_next) {
                        if ( tmp == *at ) {
                                break;
                        }
@@ -237,7 +245,7 @@ at_next( AttributeType **at )
        }
 #endif
 
-       *at = (*at)->sat_next;
+       *at = LDAP_SLIST_NEXT(*at,sat_next);
 
        return (*at != NULL);
 }
@@ -250,15 +258,10 @@ at_insert(
     const char         **err
 )
 {
-       AttributeType           **atp;
        struct aindexrec        *air;
        char                    **names;
 
-       atp = &attr_list;
-       while ( *atp != NULL ) {
-               atp = &(*atp)->sat_next;
-       }
-       *atp = sat;
+       LDAP_SLIST_INSERT_HEAD( &attr_list, sat, sat_next );
 
        if ( sat->sat_oid ) {
                air = (struct aindexrec *)
@@ -267,8 +270,7 @@ at_insert(
                air->air_name.bv_len = strlen(sat->sat_oid);
                air->air_at = sat;
                if ( avl_insert( &attr_index, (caddr_t) air,
-                                (AVL_CMP) attr_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
+                                attr_index_cmp, avl_dup_error ) ) {
                        *err = sat->sat_oid;
                        ldap_memfree(air);
                        return SLAP_SCHERR_ATTR_DUP;
@@ -285,8 +287,7 @@ at_insert(
                        air->air_name.bv_len = strlen(*names);
                        air->air_at = sat;
                        if ( avl_insert( &attr_index, (caddr_t) air,
-                                        (AVL_CMP) attr_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) ) {
+                                        attr_index_cmp, avl_dup_error ) ) {
                                *err = *names;
                                ldap_memfree(air);
                                return SLAP_SCHERR_ATTR_DUP;
@@ -377,9 +378,6 @@ at_add(
                        /* collective attributes cannot be single-valued */
                        return SLAP_SCHERR_ATTR_BAD_USAGE;
                }
-
-               /* collective attributes not supported */
-               return SLAP_SCHERR_NOT_SUPPORTED;
        }
 
        sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
@@ -570,9 +568,9 @@ at_add(
 
 #ifdef LDAP_DEBUG
 static int
-at_index_printnode( struct aindexrec *air )
+at_index_printnode( void *v_air, void *ignore )
 {
-
+       struct aindexrec *air = v_air;
        printf("%s = %s\n",
                air->air_name.bv_val,
                ldap_attributetype2str(&air->air_at->sat_atype) );
@@ -583,8 +581,7 @@ static void
 at_index_print( void )
 {
        printf("Printing attribute type index:\n");
-       (void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
-               0, -1, AVL_INORDER );
+       (void) avl_apply( attr_index, at_index_printnode, 0, -1, AVL_INORDER );
 }
 #endif
 
@@ -598,7 +595,7 @@ at_schema_info( Entry *e )
 
        vals[1].bv_val = NULL;
 
-       for ( at = attr_list; at; at = at->sat_next ) {
+       LDAP_SLIST_FOREACH(at,&attr_list,sat_next) {
                if( at->sat_flags & SLAP_AT_HIDE ) continue;
 
                if ( ldap_attributetype2bv( &at->sat_atype, vals ) == NULL ) {
index 3644280e08166e49f11b0adf843d985c0b935326..ccee12cdc363e7a2381aa80bfae4dc56c80b6ae0 100644 (file)
@@ -4,12 +4,12 @@ SRCS = init.c tools.c config.c \
        add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
        extended.c passwd.c referral.c attribute.c group.c operational.c \
        attr.c index.c key.c dbcache.c filterindex.c \
-       dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c lcup.c
+       dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c psearch.c
 OBJS = init.lo tools.lo config.lo \
        add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
        extended.lo passwd.lo referral.lo attribute.lo group.lo operational.lo \
        attr.lo index.lo key.lo dbcache.lo filterindex.lo \
-       dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo lcup.lo
+       dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo psearch.lo
 
 LDAP_INCDIR= ../../../include       
 LDAP_LIBDIR= ../../../libraries
index 286c44f864e638731176995a4744a76858578b09..3e85b1a7ad04343114f135f79f7bdbb99f916e54 100644 (file)
@@ -1,7 +1,7 @@
 /* add.c - ldap BerkeleyDB back-end add routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -34,7 +34,7 @@ bdb_add(
 #ifdef BDB_SUBENTRIES
        int subentry;
 #endif
-       u_int32_t       locker;
+       u_int32_t       locker = 0;
        DB_LOCK         lock;
 #if 0
        u_int32_t       lockid;
@@ -42,7 +42,7 @@ bdb_add(
 #endif
        int             noop = 0;
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        Operation* ps_list;
 #endif
 
@@ -132,6 +132,7 @@ retry:      /* transaction retry */
 
        opinfo.boi_bdb = be;
        opinfo.boi_txn = ltid;
+       opinfo.boi_locker = locker;
        opinfo.boi_err = 0;
        op->o_private = &opinfo;
        
@@ -547,10 +548,10 @@ return_results:
        send_ldap_result( conn, op, rc,
                NULL, text, NULL, NULL );
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        if ( rc == LDAP_SUCCESS && !noop ) {
                LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
-                       bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_ADD );
+                       bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_ADD );
                }
        }
 #endif /* LDAP_CLIENT_UPDATE */
index 07bfc92cabec4f606fb32f8d4c53b8e3466a4c4e..a5bfc4fd571e9e4b97a79dc2340413b812b3bd49 100644 (file)
@@ -1,7 +1,7 @@
 /* attr.c - backend routines for dealing with attributes */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -23,19 +23,22 @@ typedef struct bdb_attrinfo {
 
 static int
 ainfo_type_cmp(
-       AttributeDescription *desc,
-       AttrInfo        *a
+       const void *v_desc,
+       const void *v_a
 )
 {
+       const AttributeDescription *desc = v_desc;
+       const AttrInfo  *a = v_a;
        return desc - a->ai_desc;
 }
 
 static int
 ainfo_cmp(
-       AttrInfo        *a,
-       AttrInfo        *b
+       const void      *v_a,
+       const void      *v_b
 )
 {
+       const AttrInfo *a = v_a, *b = v_b;
        return a->ai_desc - b->ai_desc;
 }
 
@@ -47,8 +50,7 @@ bdb_attr_mask(
 {
        AttrInfo        *a;
 
-       a = (AttrInfo *) avl_find( bdb->bi_attrs, desc,
-               (AVL_CMP) ainfo_type_cmp );
+       a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
        
        *indexmask = a != NULL ? a->ai_indexmask : 0;
 }
@@ -194,7 +196,7 @@ bdb_attr_index_config(
                a->ai_indexmask = mask;
 
                rc = avl_insert( &bdb->bi_attrs, (caddr_t) a,
-                       (AVL_CMP) ainfo_cmp, (AVL_DUP) avl_dup_error );
+                                ainfo_cmp, avl_dup_error );
 
                if( rc ) {
                        fprintf( stderr, "%s: line %d: duplicate index definition "
index 8b7ec4b8e49a672c30865d701316a5de3b5e0f2f..10ef737faecd7d5edd2b73b915d41bb07e395e47 100644 (file)
@@ -1,7 +1,7 @@
 /* attribute.c - bdb backend acl attribute routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -39,38 +39,41 @@ bdb_attribute(
        const char *entry_at_name = entry_at->ad_cname.bv_val;
        AccessControlState acl_state = ACL_STATE_INIT;
 
-       u_int32_t       locker;
+       u_int32_t       locker = 0;
        DB_LOCK         lock;
+       int             free_lock_id = 0;
 
 #ifdef NEW_LOGGING
        LDAP_LOG( BACK_BDB, ARGS, 
-               "bdb_attribute: gr dn: \"%s\"\n", entry_ndn->bv_val, 0, 0 );
+               "bdb_attribute: gr ndn: \"%s\"\n", entry_ndn->bv_val, 0, 0 );
        LDAP_LOG( BACK_BDB, ARGS, 
                "bdb_attribute: at: \"%s\"\n", entry_at_name, 0, 0);
-       LDAP_LOG( BACK_BDB, ARGS, "bdb_attribute: tr dn: \"%s\"\n",
+       LDAP_LOG( BACK_BDB, ARGS, "bdb_attribute: tr ndn: \"%s\"\n",
                target ? target->e_ndn : "", 0, 0 );
 #else
        Debug( LDAP_DEBUG_ARGS,
-               "=> bdb_attribute: gr dn: \"%s\"\n",
+               "=> bdb_attribute: gr ndn: \"%s\"\n",
                entry_ndn->bv_val, 0, 0 ); 
        Debug( LDAP_DEBUG_ARGS,
                "=> bdb_attribute: at: \"%s\"\n", 
                entry_at_name, 0, 0 ); 
 
        Debug( LDAP_DEBUG_ARGS,
-               "=> bdb_attribute: tr dn: \"%s\"\n",
+               "=> bdb_attribute: tr ndn: \"%s\"\n",
                target ? target->e_ndn : "", 0, 0 ); 
 #endif
 
        if( op ) boi = (struct bdb_op_info *) op->o_private;
        if( boi != NULL && be == boi->boi_bdb ) {
                txn = boi->boi_txn;
+               locker = boi->boi_locker;
        }
 
        if ( txn != NULL ) {
                locker = TXN_ID ( txn );
-       } else {
+       } else if ( !locker ) {
                rc = LOCK_ID ( bdb->bi_dbenv, &locker );
+               free_lock_id = 1;
                switch(rc) {
                case 0:
                        break;
@@ -103,10 +106,8 @@ dn2entry_retry:
                case DB_LOCK_NOTGRANTED:
                        goto dn2entry_retry;
                default:
-                       if( txn != NULL ) {
-                               boi->boi_err = rc;
-                       }
-                       else {
+                       boi->boi_err = rc;
+                       if ( free_lock_id ) {
                                LOCK_ID_FREE( bdb->bi_dbenv, locker );
                        }
                        return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
@@ -121,7 +122,7 @@ dn2entry_retry:
                                "=> bdb_attribute: cannot find entry: \"%s\"\n",
                                        entry_ndn->bv_val, 0, 0 ); 
 #endif
-                       if ( txn == NULL ) {
+                       if ( free_lock_id ) {
                                LOCK_ID_FREE( bdb->bi_dbenv, locker );
                        }
                        return LDAP_NO_SUCH_OBJECT; 
@@ -221,7 +222,7 @@ return_results:
                bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
        }
 
-       if ( txn == NULL ) {
+       if ( free_lock_id ) {
                LOCK_ID_FREE( bdb->bi_dbenv, locker );
        }
 
index b7d208812a13b0f9cba640483e738d4f41d1a350..5a28d25581beda00a009eaa534f845a1a21a0ffd 100644 (file)
@@ -1,7 +1,7 @@
 /* back-bdb.h - bdb back-end header file */
 /* $OpenLDAP$ */
 /*
- * Copyright 2000-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -63,7 +63,9 @@ LDAP_BEGIN_DECL
 /* The default search IDL stack cache depth */
 #define DEFAULT_SEARCH_STACK_DEPTH     16
 
-/* for the (expermental) IDL cache */
+/* for the IDL cache */
+#define SLAP_IDL_CACHE 1
+
 #ifdef SLAP_IDL_CACHE
 typedef struct bdb_idl_cache_entry_s {
        struct berval kstr;
@@ -130,7 +132,7 @@ struct bdb_info {
 
        ID                      bi_lastid;
        ldap_pvt_thread_mutex_t bi_lastid_mutex;
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        LDAP_LIST_HEAD(pl, slap_op) psearch_list;
 #endif
 #ifdef SLAP_IDL_CACHE
@@ -153,7 +155,8 @@ struct bdb_info {
 struct bdb_op_info {
        BackendDB*      boi_bdb;
        DB_TXN*         boi_txn;
-       int                     boi_err;
+       u_int32_t       boi_err;
+       u_int32_t       boi_locker;
 };
 
 #define        DB_OPEN(db, file, name, type, flags, mode) \
index f13338cdc0b77407822f9a0bf154e61fb170da1b..f03ea7487d6e372167da1d64805bbddac5c195f8 100644 (file)
@@ -1,7 +1,7 @@
 /* bind.c - bdb backend bind routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -302,6 +302,6 @@ done:
 
        LOCK_ID_FREE(bdb->bi_dbenv, locker);
 
-       /* front end with send result on success (rc==0) */
+       /* front end will send result on success (rc==0) */
        return rc;
 }
index ab0cec701cae25978bcb42362e81f40579b4940f..ad98106a69783ffd9ccbc5fc6f31b6d745e908b0 100644 (file)
@@ -1,7 +1,7 @@
 /* cache.c - routines to maintain an in-core cache of entries */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -491,7 +491,7 @@ bdb_cache_add_entry_rw(
        }
 
        if ( avl_insert( &cache->c_dntree, (caddr_t) e,
-               (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
+                        entry_dn_cmp, avl_dup_error ) != 0 )
        {
                /* free cache write lock */
                ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
@@ -513,7 +513,7 @@ bdb_cache_add_entry_rw(
 
        /* id tree */
        if ( avl_insert( &cache->c_idtree, (caddr_t) e,
-               (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
+                        entry_id_cmp, avl_dup_error ) != 0 )
        {
 #ifdef NEW_LOGGING
                LDAP_LOG( CACHE, DETAIL1, 
@@ -527,7 +527,7 @@ bdb_cache_add_entry_rw(
 
                /* delete from dn tree inserted above */
                if ( avl_delete( &cache->c_dntree, (caddr_t) e,
-                       (AVL_CMP) entry_dn_cmp ) == NULL )
+                                entry_dn_cmp ) == NULL )
                {
 #ifdef NEW_LOGGING
                        LDAP_LOG( CACHE, INFO, 
@@ -554,7 +554,7 @@ bdb_cache_add_entry_rw(
        case DB_LOCK_NOTGRANTED :
                /* undo avl changes immediately */
                if ( avl_delete( &cache->c_idtree, (caddr_t) e,
-                       (AVL_CMP) entry_id_cmp ) == NULL ) {
+                                entry_id_cmp ) == NULL ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG( CACHE, INFO, 
                                "bdb_cache_add_entry: can't delete (%s) from cache.\n", 
@@ -564,7 +564,7 @@ bdb_cache_add_entry_rw(
 #endif
                }
                if ( avl_delete( &cache->c_dntree, (caddr_t) e,
-                               (AVL_CMP) entry_dn_cmp ) == NULL ) {
+                                entry_dn_cmp ) == NULL ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG( CACHE, INFO, 
                                "bdb_cache_add_entry: can't delete (%s) from cache.\n", 
@@ -653,7 +653,7 @@ bdb_cache_update_entry(
        assert( e->e_private );
 
        if ( avl_insert( &cache->c_dntree, (caddr_t) e,
-               (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
+                        entry_dn_cmp, avl_dup_error ) != 0 )
        {
 #ifdef NEW_LOGGING
                LDAP_LOG( CACHE, DETAIL1, 
@@ -672,7 +672,7 @@ bdb_cache_update_entry(
 
        /* id tree */
        if ( avl_insert( &cache->c_idtree, (caddr_t) e,
-               (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
+                        entry_id_cmp, avl_dup_error ) != 0 )
        {
 #ifdef NEW_LOGGING
                LDAP_LOG( CACHE, DETAIL1, 
@@ -686,7 +686,7 @@ bdb_cache_update_entry(
 
                /* delete from dn tree inserted above */
                if ( avl_delete( &cache->c_dntree, (caddr_t) e,
-                       (AVL_CMP) entry_dn_cmp ) == NULL )
+                                entry_dn_cmp ) == NULL )
                {
 #ifdef NEW_LOGGING
                        LDAP_LOG( CACHE, INFO, 
@@ -774,7 +774,7 @@ try_again:
        ldap_pvt_thread_rdwr_rlock( &cache->c_rwlock );
 
        if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e,
-               (AVL_CMP) entry_dn_cmp )) != NULL )
+                                      entry_dn_cmp )) != NULL )
        {
                int state;
                count++;
@@ -874,7 +874,7 @@ try_again:
        ldap_pvt_thread_rdwr_rlock( &cache->c_rwlock );
 
        if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e,
-               (AVL_CMP) entry_id_cmp )) != NULL )
+                                      entry_id_cmp )) != NULL )
        {
                int state;
                ID      ep_id;
@@ -1029,15 +1029,13 @@ bdb_cache_delete_entry_internal(
        int rc = 0;     /* return code */
 
        /* dn tree */
-       if ( avl_delete( &cache->c_dntree, (caddr_t) e, (AVL_CMP) entry_dn_cmp )
-               == NULL )
+       if ( avl_delete( &cache->c_dntree, (caddr_t) e, entry_dn_cmp ) == NULL )
        {
                rc = -1;
        }
 
        /* id tree */
-       if ( avl_delete( &cache->c_idtree, (caddr_t) e, (AVL_CMP) entry_id_cmp )
-               == NULL )
+       if ( avl_delete( &cache->c_idtree, (caddr_t) e, entry_id_cmp ) == NULL )
        {
                rc = -1;
        }
index 8d4c14e9c724c90b5b98205a085acb3eb1ee511d..79cb4608439ce6c7225257a4978302f433f978dd 100644 (file)
@@ -1,7 +1,7 @@
 /* delete.c - bdb backend delete routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -35,7 +35,7 @@ bdb_delete(
        DB_TXN          *ltid = NULL;
        struct bdb_op_info opinfo;
 
-       u_int32_t       locker;
+       u_int32_t       locker = 0;
        DB_LOCK         lock;
 #if 0
        u_int32_t       lockid;
@@ -44,7 +44,7 @@ bdb_delete(
 
        int             noop = 0;
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        Operation* ps_list;
 #endif
 
@@ -104,6 +104,7 @@ retry:      /* transaction retry */
 
        opinfo.boi_bdb = be;
        opinfo.boi_txn = ltid;
+       opinfo.boi_locker = locker;
        opinfo.boi_err = 0;
        op->o_private = &opinfo;
 
@@ -493,13 +494,13 @@ retry:    /* transaction retry */
 return_results:
        send_ldap_result( conn, op, rc, NULL, text, NULL, NULL );
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
         if ( rc == LDAP_SUCCESS && !noop ) {
                LDAP_LIST_FOREACH( ps_list, &bdb->psearch_list, link ) {
-                       bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_DELETE );
+                       bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_DELETE );
                }
        }
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
 
        if(rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
                ldap_pvt_thread_yield();
index eb3600c9406ba1c60bd139774617271ce969b7a6..d3e0ede9573c6ec4662491a7f763a00bb76ffeea 100644 (file)
@@ -1,7 +1,7 @@
 /* dn2id.c - routines to deal with the dn2id index */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -67,22 +67,27 @@ bdb_dn2id_add(
                goto done;
        }
 
+#ifndef BDB_MULTIPLE_SUFFIXES
        if( !be_issuffix( be, &ptr )) {
+#endif
                buf[0] = DN_SUBTREE_PREFIX;
-               rc = bdb_idl_insert_key( be, db, txn, &key, e->e_id );
+               rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
                if( rc != 0 ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG ( INDEX, ERR, 
-                               "=> bdb_dn2id_add: subtree (%s) insert failed: %d\n",
+                               "=> bdb_dn2id_add: subtree (%s) put failed: %d\n",
                                ptr.bv_val, rc, 0 );
 #else
                        Debug( LDAP_DEBUG_ANY,
-                       "=> bdb_dn2id_add: subtree (%s) insert failed: %d\n",
+                       "=> bdb_dn2id_add: subtree (%s) put failed: %d\n",
                        ptr.bv_val, rc, 0 );
 #endif
                        goto done;
                }
                
+#ifdef BDB_MULTIPLE_SUFFIXES
+       if( !be_issuffix( be, &ptr )) {
+#endif
                dnParent( &ptr, &pdn );
        
                key.size = pdn.bv_len + 2;
@@ -105,9 +110,13 @@ bdb_dn2id_add(
 #endif
                        goto done;
                }
+#ifndef BDB_MULTIPLE_SUFFIXES
        }
 
        while( !be_issuffix( be, &ptr )) {
+#else
+       for (;;) {
+#endif
                ptr.bv_val[-1] = DN_SUBTREE_PREFIX;
 
                rc = bdb_idl_insert_key( be, db, txn, &key, e->e_id );
@@ -124,6 +133,9 @@ bdb_dn2id_add(
 #endif
                        break;
                }
+#ifdef BDB_MULTIPLE_SUFFIXES
+               if( be_issuffix( be, &ptr )) break;
+#endif
                dnParent( &ptr, &pdn );
 
                key.size = pdn.bv_len + 2;
@@ -131,6 +143,9 @@ bdb_dn2id_add(
                key.data = pdn.bv_val - 1;
                ptr = pdn;
        }
+#ifdef BDB_MULTIPLE_SUFFIXES
+       }
+#endif
 
 done:
        ch_free( buf );
@@ -189,7 +204,9 @@ bdb_dn2id_delete(
                goto done;
        }
 
+#ifndef BDB_MULTIPLE_SUFFIXES
        if( !be_issuffix( be, &ptr )) {
+#endif
                buf[0] = DN_SUBTREE_PREFIX;
                rc = db->del( db, txn, &key, 0 );
                if( rc != 0 ) {
@@ -205,6 +222,9 @@ bdb_dn2id_delete(
                        goto done;
                }
 
+#ifdef BDB_MULTIPLE_SUFFIXES
+       if( !be_issuffix( be, &ptr )) {
+#endif
                dnParent( &ptr, &pdn );
 
                key.size = pdn.bv_len + 2;
@@ -227,9 +247,13 @@ bdb_dn2id_delete(
 #endif
                        goto done;
                }
+#ifndef BDB_MULTIPLE_SUFFIXES
        }
 
        while( !be_issuffix( be, &ptr )) {
+#else
+       for (;;) {
+#endif
                ptr.bv_val[-1] = DN_SUBTREE_PREFIX;
 
                rc = bdb_idl_delete_key( be, db, txn, &key, e->e_id );
@@ -245,6 +269,9 @@ bdb_dn2id_delete(
 #endif
                        goto done;
                }
+#ifdef BDB_MULTIPLE_SUFFIXES
+               if( be_issuffix( be, &ptr )) break;
+#endif
                dnParent( &ptr, &pdn );
 
                key.size = pdn.bv_len + 2;
@@ -252,6 +279,9 @@ bdb_dn2id_delete(
                key.data = pdn.bv_val - 1;
                ptr = pdn;
        }
+#ifdef BDB_MULTIPLE_SUFFIXES
+       }
+#endif
 
 done:
        ch_free( buf );
@@ -525,11 +555,13 @@ bdb_dn2idl(
        Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2idl( \"%s\" )\n", dn->bv_val, 0, 0 );
 #endif
 
+#ifndef        BDB_MULTIPLE_SUFFIXES
        if (prefix == DN_SUBTREE_PREFIX && be_issuffix(be, dn))
        {
                BDB_IDL_ALL(bdb, ids);
                return 0;
        }
+#endif
 
        DBTzero( &key );
        key.size = dn->bv_len + 2;
@@ -622,28 +654,32 @@ node_find_cmp(
 
 static int
 node_frdn_cmp(
-       struct berval *nrdn,
-       idNode *n
+       const void *v_nrdn,
+       const void *v_n
 )
 {
+       const struct berval *nrdn = v_nrdn;
+       const idNode *n = v_n;
        return ber_bvcmp(nrdn, &n->i_rdn->nrdn);
 }
 
 static int
 node_add_cmp(
-       idNode *a,
-       idNode *b
+       const void *v_a,
+       const void *v_b
 )
 {
+       const idNode *a = v_a, *b = v_b;
        return a->i_id - b->i_id;
 }
 
 static int
 node_rdn_cmp(
-       idNode *a,
-       idNode *b
+       const void *v_a,
+       const void *v_b
 )
 {
+       const idNode *a = v_a, *b = v_b;
        /* should be slightly better without ordering drawbacks */
        return ber_bvcmp(&a->i_rdn->nrdn, &b->i_rdn->nrdn);
 }
@@ -661,15 +697,17 @@ idNode * bdb_find_rdn_node(
        Avlnode *tree
 )
 {
-       return avl_find(tree, (const void *)nrdn, (AVL_CMP)node_frdn_cmp);
+       return avl_find(tree, nrdn, node_frdn_cmp);
 }
 
 /* This function links a node into its parent's i_kids tree. */
-int bdb_insert_kid(
-       idNode *a,
-       Avlnode *tree
+static int bdb_insert_kid(
+       void *v_a,
+       void *v_tree
 )
 {
+       idNode *a = v_a;
+       Avlnode *tree = v_tree;
        int rc;
 
        if (a->i_rdn->parent == 0)
@@ -679,7 +717,7 @@ int bdb_insert_kid(
                return -1;
        ldap_pvt_thread_rdwr_wlock(&a->i_parent->i_kids_rdwr);
        rc = avl_insert( &a->i_parent->i_kids, (caddr_t) a,
-               (AVL_CMP)node_rdn_cmp, (AVL_DUP) avl_dup_error );
+                        node_rdn_cmp, avl_dup_error );
        ldap_pvt_thread_rdwr_wunlock(&a->i_parent->i_kids_rdwr);
        return rc;
 }
@@ -701,8 +739,7 @@ idNode *bdb_add_node(
        node->i_rdn->rdn.bv_val += (long)d;
        node->i_rdn->nrdn.bv_val += (long)d;
        ldap_pvt_thread_rdwr_init(&node->i_kids_rdwr);
-       avl_insert( &bdb->bi_tree, (caddr_t) node,
-                       (AVL_CMP)node_add_cmp, (AVL_DUP) avl_dup_error );
+       avl_insert( &bdb->bi_tree, (caddr_t) node, node_add_cmp, avl_dup_error );
        if (id == 1)
                bdb->bi_troot = node;
        return node;
@@ -741,7 +778,7 @@ int bdb_build_tree(
        }
        cursor->c_close( cursor );
 
-       rc = avl_apply(bdb->bi_tree, (AVL_APPLY)bdb_insert_kid, bdb->bi_tree,
+       rc = avl_apply(bdb->bi_tree, bdb_insert_kid, bdb->bi_tree,
                -1, AVL_INORDER );
 
        return rc;
@@ -880,8 +917,7 @@ bdb_dn2id_delete(
        if (n) {
                if (n->i_parent) {
                        ldap_pvt_thread_rdwr_wlock(&n->i_parent->i_kids_rdwr);
-                       avl_delete(&n->i_parent->i_kids, &n->i_rdn->nrdn,
-                               (AVL_CMP)node_frdn_cmp);
+                       avl_delete(&n->i_parent->i_kids, &n->i_rdn->nrdn, node_frdn_cmp);
                        ldap_pvt_thread_rdwr_wunlock(&n->i_parent->i_kids_rdwr);
                }
                free(n->i_rdn);
@@ -908,6 +944,7 @@ bdb_dn2id_matched(
        struct berval   rdn;
        char            *p1, *p2;
        idNode *n, *p;
+       int             rc = 0;
 
        if (!bdb->bi_troot)
                return DB_NOTFOUND;
@@ -940,8 +977,11 @@ bdb_dn2id_matched(
                *id = n->i_id;
        } else if (id2) {
                *id2 = p->i_id;
+       } else {
+               rc = DB_NOTFOUND;
        }
-       return n ? 0 : DB_NOTFOUND;
+
+       return rc;
 }
 
 int
@@ -986,26 +1026,29 @@ bdb_dn2id_children(
  */
 static int
 insert_one(
-       idNode *n,
-       ID *ids
+       void *v_n,
+       void *v_ids
 )
 {
+       idNode *n = v_n;
+       ID *ids = v_ids;
        return bdb_idl_insert(ids, n->i_id);
 }
 
 static int
 insert_sub(
-       idNode *n,
-       ID *ids
+       void *v_n,
+       void *v_ids
 )
 {
+       idNode *n = v_n;
+       ID *ids = v_ids;
        int rc;
 
        rc = bdb_idl_insert(ids, n->i_id);
        if (rc == 0) {
                ldap_pvt_thread_rdwr_rlock(&n->i_kids_rdwr);
-               rc = avl_apply(n->i_kids, (AVL_APPLY)insert_sub, ids, -1,
-                       AVL_INORDER);
+               rc = avl_apply(n->i_kids, insert_sub, ids, -1, AVL_INORDER);
                ldap_pvt_thread_rdwr_runlock(&n->i_kids_rdwr);
        }
        return rc;
@@ -1038,11 +1081,12 @@ bdb_dn2idl(
        ids[0] = 0;
        ldap_pvt_thread_rdwr_rlock(&n->i_kids_rdwr);
        if (prefix == DN_ONE_PREFIX) {
-               rc = avl_apply(n->i_kids, (AVL_APPLY)insert_one, ids, -1,
-                       AVL_INORDER);
+               rc = avl_apply(n->i_kids, insert_one, ids, -1, AVL_INORDER);
        } else {
-               rc = avl_apply(n->i_kids, (AVL_APPLY)insert_sub, ids, -1,
-                       AVL_INORDER);
+               ids[0] = 1;
+               ids[1] = id;
+               if (n->i_kids)
+                       rc = avl_apply(n->i_kids, insert_sub, ids, -1, AVL_INORDER);
        }
        ldap_pvt_thread_rdwr_runlock(&n->i_kids_rdwr);
        return rc;
index 9e595ef9ff622a4342f8578969c19a2537092282..b2ef1e3bcd97c126f85aea95be5a148cdef7c6a5 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 2000-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -33,9 +33,7 @@ extern BI_chk_referrals       bdb_referrals;
 
 extern BI_operational  bdb_operational;
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
 extern BI_has_subordinates bdb_hasSubordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
 /* tools.c */
 extern BI_tool_entry_open      bdb_tool_entry_open;
index 45122f8db0d931ef60fa1df7148e3db083e865a3..80354a7b8ba094afb12ea204e8141716ca11893e 100644 (file)
@@ -1,7 +1,7 @@
 /* filterindex.c - generate the list of candidate entries from a filter */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -274,12 +274,14 @@ presence_candidates(
        DB *db;
        int rc;
        slap_mask_t mask;
-       struct berval prefix = {0};
+       struct berval prefix = {0, NULL};
 
 #ifdef NEW_LOGGING
-       LDAP_LOG ( INDEX, ENTRY, "=> bdb_presence_candidates\n", 0, 0, 0 );
+       LDAP_LOG ( INDEX, ENTRY, "=> bdb_presence_candidates (%s)\n", 
+                       desc->ad_cname.bv_val, 0, 0 );
 #else
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_presence_candidates\n", 0, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "=> bdb_presence_candidates (%s)\n",
+                       desc->ad_cname.bv_val, 0, 0 );
 #endif
 
        if( desc == slap_schema.si_ad_objectClass ) {
@@ -293,11 +295,14 @@ presence_candidates(
        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_presence_candidates: index_param returned=%d\n", rc, 0, 0 );
+                       "<= bdb_presence_candidates: (%s) index_param "
+                       "returned=%d\n",
+                       desc->ad_cname.bv_val, rc, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_presence_candidates: index_param returned=%d\n",
-                       rc, 0, 0 );
+                       "<= bdb_presence_candidates: (%s) index_param "
+                       "returned=%d\n",
+                       desc->ad_cname.bv_val, rc, 0 );
 #endif
                return 0;
        }
@@ -306,11 +311,12 @@ presence_candidates(
                /* not indexed */
 #ifdef NEW_LOGGING
                LDAP_LOG(INDEX, RESULTS, 
-                       "<= bdb_presence_candidates: not indexed\n", 0, 0, 0 );
+                       "<= bdb_presence_candidates: (%s) not indexed\n",
+                       desc->ad_cname.bv_val, 0, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_presence_candidates: not indexed\n",
-                       0, 0, 0 );
+                       "<= bdb_presence_candidates: (%s) not indexed\n",
+                       desc->ad_cname.bv_val, 0, 0 );
 #endif
                return 0;
        }
@@ -318,11 +324,12 @@ presence_candidates(
        if( prefix.bv_val == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(INDEX, RESULTS, 
-                       "<= bdb_presence_candidates: no prefix\n", 0, 0, 0 );
+                       "<= bdb_presence_candidates: (%s) no prefix\n",
+                       desc->ad_cname.bv_val, 0, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_presence_candidates: no prefix\n",
-                       0, 0, 0 );
+                       "<= bdb_presence_candidates: (%s) no prefix\n",
+                       desc->ad_cname.bv_val, 0, 0 );
 #endif
                return 0;
        }
@@ -335,11 +342,14 @@ presence_candidates(
        } else if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_presence_candidates: key read failed (%d)\n", rc, 0, 0 );
+                       "<= bdb_presence_candidates: (%s) "
+                       "key read failed (%d)\n",
+                       desc->ad_cname.bv_val, rc, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_presense_candidates: key read failed (%d)\n",
-                       rc, 0, 0 );
+                       "<= bdb_presense_candidates: (%s) "
+                       "key read failed (%d)\n",
+                       desc->ad_cname.bv_val, rc, 0 );
 #endif
                goto done;
        }
@@ -371,14 +381,16 @@ equality_candidates(
        int i;
        int rc;
        slap_mask_t mask;
-       struct berval prefix = {0};
+       struct berval prefix = {0, NULL};
        struct berval *keys = NULL;
        MatchingRule *mr;
 
 #ifdef NEW_LOGGING
-       LDAP_LOG ( INDEX, ENTRY, "=> bdb_equality_candidates\n", 0, 0, 0 );
+       LDAP_LOG ( INDEX, ENTRY, "=> bdb_equality_candidates (%s)\n",
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #else
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_equality_candidates\n", 0, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "=> bdb_equality_candidates (%s)\n",
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #endif
 
        rc = bdb_index_param( be, ava->aa_desc, LDAP_FILTER_EQUALITY,
@@ -387,11 +399,14 @@ equality_candidates(
        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_equality_candidates: index_param failed (%d)\n", rc, 0, 0);
+                       "<= bdb_equality_candidates: (%s) "
+                       "index_param failed (%d)\n", 
+                       ava->aa_desc->ad_cname.bv_val, rc, 0);
 #else
                Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_equality_candidates: index_param failed (%d)\n",
-                       rc, 0, 0 );
+                       "<= bdb_equality_candidates: (%s) "
+                       "index_param failed (%d)\n",
+                       ava->aa_desc->ad_cname.bv_val, rc, 0 );
 #endif
                return rc;
        }
@@ -399,10 +414,12 @@ equality_candidates(
        if ( db == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(INDEX, RESULTS, 
-                       "<= bdb_equality_candidates: not indexed\n", 0, 0, 0 );
+                       "<= bdb_equality_candidates: (%s) not indexed\n", 
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #else
                Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_equality_candidates: not indexed\n", 0, 0, 0 );
+                       "<= bdb_equality_candidates: (%s) not indexed\n", 
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #endif
                return -1;
        }
@@ -428,12 +445,14 @@ equality_candidates(
        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_equality_candidates: (%s) MR filter failed (%d)\n",
-                       prefix.bv_val, rc, 0 );
+                       "<= bdb_equality_candidates: (%s, %s) "
+                       "MR filter failed (%d)\n",
+                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_equality_candidates: (%s) MR filter failed (%d)\n",
-                       prefix.bv_val, rc, 0 );
+                       "<= bdb_equality_candidates: (%s, %s) "
+                       "MR filter failed (%d)\n",
+                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
 #endif
                return rc;
        }
@@ -441,11 +460,12 @@ equality_candidates(
        if( keys == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_equality_candidates: no keys\n", 0, 0, 0 );
+                       "<= bdb_equality_candidates: (%s) no keys\n", 
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_equality_candidates: no keys\n",
-                       0, 0, 0 );
+                       "<= bdb_equality_candidates: (%s) no keys\n",
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #endif
                return 0;
        }
@@ -459,11 +479,14 @@ equality_candidates(
                } else if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG ( INDEX, RESULTS, 
-                               "<= bdb_equality_candidates: key read failed (%d)\n", rc, 0, 0);
+                               "<= bdb_equality_candidates: (%s) "
+                               "key read failed (%d)\n",
+                               ava->aa_desc->ad_cname.bv_val, rc, 0 );
 #else
                        Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb_equality_candidates: key read failed (%d)\n",
-                               rc, 0, 0 );
+                               "<= bdb_equality_candidates: (%s) "
+                               "key read failed (%d)\n",
+                               ava->aa_desc->ad_cname.bv_val, rc, 0 );
 #endif
                        break;
                }
@@ -471,11 +494,12 @@ equality_candidates(
                if( BDB_IDL_IS_ZERO( tmp ) ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG ( INDEX, RESULTS,
-                               "<= bdb_equality_candidates: NULL\n", 0, 0, 0);
+                               "<= bdb_equality_candidates: (%s) NULL\n",
+                               ava->aa_desc->ad_cname.bv_val, 0, 0);
 #else
                        Debug( LDAP_DEBUG_TRACE,
-                               "<= bdb_equality_candidates: NULL\n",
-                               0, 0, 0 );
+                               "<= bdb_equality_candidates: (%s) NULL\n", 
+                               ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #endif
                        BDB_IDL_ZERO( ids );
                        break;
@@ -516,14 +540,16 @@ approx_candidates(
        int i;
        int rc;
        slap_mask_t mask;
-       struct berval prefix = {0};
+       struct berval prefix = {0, NULL};
        struct berval *keys = NULL;
        MatchingRule *mr;
 
 #ifdef NEW_LOGGING
-       LDAP_LOG ( INDEX, ENTRY, "=> bdb_approx_candidates\n", 0, 0, 0 );
+       LDAP_LOG ( INDEX, ENTRY, "=> bdb_approx_candidates (%s)\n",
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #else
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_approx_candidates\n", 0, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "=> bdb_approx_candidates (%s)\n",
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #endif
 
        rc = bdb_index_param( be, ava->aa_desc, LDAP_FILTER_APPROX,
@@ -532,11 +558,14 @@ approx_candidates(
        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_approx_candidates: index_param failed (%d)\n", rc, 0, 0 );
+                       "<= bdb_approx_candidates: (%s) "
+                       "index_param failed (%d)\n",
+                       ava->aa_desc->ad_cname.bv_val, rc, 0 );
 #else
                Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_approx_candidates: index_param failed (%d)\n",
-                       rc, 0, 0 );
+                       "<= bdb_approx_candidates: (%s) "
+                       "index_param failed (%d)\n",
+                       ava->aa_desc->ad_cname.bv_val, rc, 0 );
 #endif
                return rc;
        }
@@ -544,10 +573,12 @@ approx_candidates(
        if ( db == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG(INDEX, RESULTS, 
-                       "<= bdb_approx_candidates: not indexed\n",0, 0, 0 );
+                       "<= bdb_approx_candidates: (%s) not indexed\n",
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #else
                Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_approx_candidates: not indexed\n", 0, 0, 0 );
+                       "<= bdb_approx_candidates: (%s) not indexed\n",
+                       ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #endif
                return -1;
        }
@@ -578,12 +609,14 @@ approx_candidates(
        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_approx_candidates: (%s) MR filter failed (%d)\n",
-                       prefix.bv_val, rc, 0 );
+                       "<= bdb_approx_candidates: (%s, %s) "
+                       "MR filter failed (%d)\n",
+                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_approx_candidates: (%s) MR filter failed (%d)\n",
-                       prefix.bv_val, rc, 0 );
+                       "<= bdb_approx_candidates: (%s, %s) "
+                       "MR filter failed (%d)\n",
+                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
 #endif
                return rc;
        }
@@ -591,11 +624,12 @@ approx_candidates(
        if( keys == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_approx_candidates: no keys (%s)\n", prefix.bv_val, 0, 0 );
+                       "<= bdb_approx_candidates: (%s) no keys (%s)\n",
+                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_approx_candidates: no keys (%s)\n",
-                       prefix.bv_val, 0, 0 );
+                       "<= bdb_approx_candidates: (%s) no keys (%s)\n",
+                       prefix.bv_val, ava->aa_desc->ad_cname.bv_val, 0 );
 #endif
                return 0;
        }
@@ -609,11 +643,15 @@ approx_candidates(
                        break;
                } else if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
-               LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_approx_candidates: key read failed (%d)\n", rc, 0, 0);
+                       LDAP_LOG ( INDEX, RESULTS, 
+                               "<= bdb_approx_candidates: (%s) "
+                               "key read failed (%d)\n",
+                               ava->aa_desc->ad_cname.bv_val, rc, 0);
 #else
-                       Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates key read failed (%d)\n",
-                               rc, 0, 0 );
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<= bdb_approx_candidates: (%s) "
+                               "key read failed (%d)\n",
+                               ava->aa_desc->ad_cname.bv_val, rc, 0 );
 #endif
                        break;
                }
@@ -621,10 +659,12 @@ approx_candidates(
                if( BDB_IDL_IS_ZERO( tmp ) ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG ( INDEX, RESULTS, 
-                               "<= bdb_approx_candidates: NULL\n", 0, 0, 0 );
+                               "<= bdb_approx_candidates: (%s) NULL\n",
+                               ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates NULL\n",
-                               0, 0, 0 );
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<= bdb_approx_candidates: (%s) NULL\n",
+                               ava->aa_desc->ad_cname.bv_val, 0, 0 );
 #endif
                        BDB_IDL_ZERO( ids );
                        break;
@@ -663,14 +703,16 @@ substring_candidates(
        int i;
        int rc;
        slap_mask_t mask;
-       struct berval prefix = {0};
+       struct berval prefix = {0, NULL};
        struct berval *keys = NULL;
        MatchingRule *mr;
 
 #ifdef NEW_LOGGING
-       LDAP_LOG ( INDEX, ENTRY, "=> bdb_substring_candidates\n", 0, 0, 0 );
+       LDAP_LOG ( INDEX, ENTRY, "=> bdb_substring_candidates (%s)\n",
+                       sub->sa_desc->ad_cname.bv_val, 0, 0 );
 #else
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_substring_candidates\n", 0, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "=> bdb_substring_candidates (%s)\n",
+                       sub->sa_desc->ad_cname.bv_val, 0, 0 );
 #endif
 
        rc = bdb_index_param( be, sub->sa_desc, LDAP_FILTER_SUBSTRINGS,
@@ -679,11 +721,14 @@ substring_candidates(
        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_substring_candidates: index_param failed (%d)\n", rc, 0, 0);
+                       "<= bdb_substring_candidates: (%s) "
+                       "index_param failed (%d)\n",
+                       sub->sa_desc->ad_cname.bv_val, rc, 0);
 #else
                Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_substring_candidates: index_param failed (%d)\n",
-                       rc, 0, 0 );
+                       "<= bdb_substring_candidates: (%s) "
+                       "index_param failed (%d)\n",
+                       sub->sa_desc->ad_cname.bv_val, rc, 0 );
 #endif
                return rc;
        }
@@ -691,11 +736,12 @@ substring_candidates(
        if ( db == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_substring_candidates: not indexed\n", 0, 0, 0 );
+                       "<= bdb_substring_candidates: (%s) not indexed\n",
+                       sub->sa_desc->ad_cname.bv_val, 0, 0 );
 #else
                Debug( LDAP_DEBUG_ANY,
-                       "<= bdb_substring_candidates: not indexed\n",
-                       0, 0, 0 );
+                       "<= bdb_substring_candidates: (%s) not indexed\n",
+                       sub->sa_desc->ad_cname.bv_val, 0, 0 );
 #endif
                return -1;
        }
@@ -722,11 +768,13 @@ substring_candidates(
        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( INDEX, RESULTS, 
-                       "<= bdb_substring_candidates: (%s) MR filter failed (%d)\n", 
+                       "<= bdb_substring_candidates: (%s) "
+                       "MR filter failed (%d)\n", 
                        sub->sa_desc->ad_cname.bv_val, rc, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<= bdb_substring_candidates: (%s) MR filter failed (%d)\n",
+                       "<= bdb_substring_candidates: (%s) "
+                       "MR filter failed (%d)\n",
                        sub->sa_desc->ad_cname.bv_val, rc, 0 );
 #endif
                return rc;
@@ -755,10 +803,14 @@ substring_candidates(
                } else if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG ( INDEX, RESULTS, 
-                               "<= bdb_substring_candidates: key read failed (%d)\n", rc, 0,0);
+                               "<= bdb_substring_candidates: (%s) "
+                               "key read failed (%d)\n",
+                               sub->sa_desc->ad_cname.bv_val, rc, 0 );
 #else
-                       Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates: key read failed (%d)\n",
-                               rc, 0, 0 );
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<= bdb_substring_candidates: (%s) "
+                               "key read failed (%d)\n",
+                               sub->sa_desc->ad_cname.bv_val, rc, 0 );
 #endif
                        break;
                }
@@ -766,10 +818,12 @@ substring_candidates(
                if( BDB_IDL_IS_ZERO( tmp ) ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG ( INDEX, RESULTS, 
-                               "<= bdb_substring_candidates: NULL \n", 0, 0, 0 );
+                               "<= bdb_substring_candidates: (%s) NULL\n",
+                               sub->sa_desc->ad_cname.bv_val, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates: NULL\n",
-                               0, 0, 0 );
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<= bdb_substring_candidates: (%s) NULL\n",
+                               sub->sa_desc->ad_cname.bv_val, 0, 0 );
 #endif
                        BDB_IDL_ZERO( ids );
                        break;
index c471433445bbd7f7c3cf23d388349e74e52e2fe9..d449056794b7b56cd6f8896e923afbeb48265f28 100644 (file)
@@ -1,7 +1,7 @@
 /* group.c - bdb backend acl group routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -42,8 +42,9 @@ bdb_group(
        const char *group_oc_name = NULL;
        const char *group_at_name = group_at->ad_cname.bv_val;
 
-       u_int32_t       locker;
+       u_int32_t       locker = 0;
        DB_LOCK         lock;
+       int             free_lock_id = 0;
 
        if( group_oc->soc_names && group_oc->soc_names[0] ) {
                group_oc_name = group_oc->soc_names[0];
@@ -70,18 +71,20 @@ bdb_group(
 
        Debug( LDAP_DEBUG_ARGS,
                "=> bdb_group: tr ndn: \"%s\"\n",
-               target->e_ndn, 0, 0 ); 
+               target ? target->e_ndn : "", 0, 0 ); 
 #endif
 
        if( op ) boi = (struct bdb_op_info *) op->o_private;
        if( boi != NULL && be == boi->boi_bdb ) {
                txn = boi->boi_txn;
+               locker = boi->boi_locker;
        }
 
        if ( txn ) {
                locker = TXN_ID( txn );
-       } else {
+       } else if ( !locker ) {
                rc = LOCK_ID ( bdb->bi_dbenv, &locker );
+               free_lock_id = 1;
                switch(rc) {
                case 0:
                        break;
@@ -90,7 +93,7 @@ bdb_group(
                }
        }
 
-       if (dn_match(&target->e_name, gr_ndn)) {
+       if ( target != NULL && dn_match( &target->e_nname, gr_ndn )) {
                /* we already have a LOCKED copy of the entry */
                e = target;
 #ifdef NEW_LOGGING
@@ -108,10 +111,8 @@ dn2entry_retry:
                if( rc ) {
                        if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED )
                                goto dn2entry_retry;
-                       if( txn ) {
-                               boi->boi_err = rc;
-                       }
-                       else {
+                       boi->boi_err = rc;
+                       if ( free_lock_id ) {
                                LOCK_ID_FREE ( bdb->bi_dbenv, locker );
                        }
                        return( 1 );
@@ -125,7 +126,7 @@ dn2entry_retry:
                                "=> bdb_group: cannot find group: \"%s\"\n",
                                        gr_ndn->bv_val, 0, 0 ); 
 #endif
-                       if ( txn == NULL ) {
+                       if ( free_lock_id ) {
                                LOCK_ID_FREE ( bdb->bi_dbenv, locker );
                        }
                        return( 1 );
@@ -236,7 +237,7 @@ return_results:
                bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
        }
 
-       if ( txn == NULL ) {
+       if ( free_lock_id ) {
                LOCK_ID_FREE ( bdb->bi_dbenv, locker );
        }
 
index 9c8c9657e4e46aef515193ff8c68254cd38abc92..5e4ef60df488d9d6ac345c49336b95af563828fa 100644 (file)
@@ -1,7 +1,7 @@
 /* id2entry.c - routines to deal with the id2entry database */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -153,7 +153,6 @@ int bdb_id2entry_rw(
                                free ( (*e)->e_private );
                        bdb_entry_return( *e );
                        *e = NULL;
-                       ch_free( data.data );
                }
                rc = ret;
        }
index e450a7c9c793f54ea1660106f95cea31b5d6cba9..1454e18f93967a9112d8e025db9bec0c2d1274cb 100644 (file)
@@ -1,7 +1,7 @@
 /* idl.c - ldap id list handling routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 #define IDL_CMP(x,y)   ( x < y ? -1 : ( x > y ? 1 : 0 ) )
 
+#ifdef SLAP_IDL_CACHE
+#define IDL_LRU_DELETE( bdb, e ) do {                                  \
+       if ( e->idl_lru_prev != NULL ) {                                \
+               e->idl_lru_prev->idl_lru_next = e->idl_lru_next;        \
+       } else {                                                        \
+               bdb->bi_idl_lru_head = e->idl_lru_next;                 \
+       }                                                               \
+       if ( e->idl_lru_next != NULL ) {                                \
+               e->idl_lru_next->idl_lru_prev = e->idl_lru_prev;        \
+       } else {                                                        \
+               bdb->bi_idl_lru_tail = e->idl_lru_prev;                 \
+       }                                                               \
+} while ( 0 )
+
+#define IDL_LRU_ADD( bdb, e ) do {                                     \
+       e->idl_lru_next = bdb->bi_idl_lru_head;                         \
+       if ( e->idl_lru_next != NULL ) {                                \
+               e->idl_lru_next->idl_lru_prev = (e);                    \
+       }                                                               \
+       (bdb)->bi_idl_lru_head = (e);                                   \
+       e->idl_lru_prev = NULL;                                         \
+       if ( (bdb)->bi_idl_lru_tail == NULL ) {                         \
+               (bdb)->bi_idl_lru_tail = (e);                           \
+       }                                                               \
+} while ( 0 )
+
+static int
+bdb_idl_entry_cmp( const void *v_idl1, const void *v_idl2 )
+{
+       const bdb_idl_cache_entry_t *idl1 = v_idl1, *idl2 = v_idl2;
+       int rc;
+
+       if ((rc = idl1->db - idl2->db )) return rc;
+       if ((rc = idl1->kstr.bv_len - idl2->kstr.bv_len )) return rc;
+       return ( memcmp ( idl1->kstr.bv_val, idl2->kstr.bv_val , idl1->kstr.bv_len ) );
+}
+#endif
+
 #if IDL_DEBUG > 0
 static void idl_check( ID *ids )
 {
@@ -262,39 +300,67 @@ bdb_idl_fetch_key(
        size_t len;
        int rc2;
        int flags = bdb->bi_db_opflags | DB_MULTIPLE;
+#ifdef SLAP_IDL_CACHE
+       bdb_idl_cache_entry_t idl_tmp;
+#endif
 
-       /* buf must be large enough to grab the entire IDL in one
-        * get(), otherwise BDB 4 will leak resources on subsequent
-        * get's. We can safely call get() twice - once for the data,
-        * and once to get the DB_NOTFOUND result meaning there's
-        * no more data. See ITS#2040 for details. This bug is fixed
-        * in BDB 4.1 so a smaller buffer will work if stack space is
-        * too limited.
+       /* If using BerkeleyDB 4.0, the buf must be large enough to
+        * grab the entire IDL in one get(), otherwise BDB will leak
+        * resources on subsequent get's.  We can safely call get()
+        * twice - once for the data, and once to get the DB_NOTFOUND
+        * result meaning there's no more data. See ITS#2040 for details.
+        * This bug is fixed in BDB 4.1 so a smaller buffer will work if
+        * stack space is too limited.
+        *
+        * configure now requires Berkeley DB 4.1.
         */
-       ID buf[BDB_IDL_DB_SIZE*5];
+#if (DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR == 0)
+#      define BDB_ENOUGH 5
+#else
+#      define BDB_ENOUGH 1
+#endif
+       ID buf[BDB_IDL_DB_SIZE*BDB_ENOUGH];
+
+       char keybuf[16];
 
-       {
-               char buf[16];
 #ifdef NEW_LOGGING
-               LDAP_LOG( INDEX, ARGS,
-                       "bdb_idl_fetch_key: %s\n", 
-                       bdb_show_key( key, buf ), 0, 0 );
+       LDAP_LOG( INDEX, ARGS,
+               "bdb_idl_fetch_key: %s\n", 
+               bdb_show_key( key, keybuf ), 0, 0 );
 #else
-               Debug( LDAP_DEBUG_ARGS,
-                       "bdb_idl_fetch_key: %s\n", 
-                       bdb_show_key( key, buf ), 0, 0 );
+       Debug( LDAP_DEBUG_ARGS,
+               "bdb_idl_fetch_key: %s\n", 
+               bdb_show_key( key, keybuf ), 0, 0 );
 #endif
-       }
+
        assert( ids != NULL );
 
+#ifdef SLAP_IDL_CACHE
+       if ( bdb->bi_idl_cache_max_size ) {
+               bdb_idl_cache_entry_t *matched_idl_entry;
+               DBT2bv( key, &idl_tmp.kstr );
+               idl_tmp.db = db;
+               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_mutex );
+               matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+                                             bdb_idl_entry_cmp );
+               if ( matched_idl_entry != NULL ) {
+                       BDB_IDL_CPY( ids, matched_idl_entry->idl );
+                       IDL_LRU_DELETE( bdb, matched_idl_entry );
+                       IDL_LRU_ADD( bdb, matched_idl_entry );
+                       ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+                       return LDAP_SUCCESS;
+               }
+               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+       }
+#endif
+
        DBTzero( &data );
 
        data.data = buf;
        data.ulen = sizeof(buf);
        data.flags = DB_DBT_USERMEM;
 
-       if ( tid )
-               flags |= DB_RMW;
+       if ( tid ) flags |= DB_RMW;
 
        rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
        if( rc != 0 ) {
@@ -308,6 +374,7 @@ bdb_idl_fetch_key(
 #endif
                return rc;
        }
+
        rc = cursor->c_get( cursor, key, &data, flags | DB_SET );
        if (rc == 0) {
                i = ids;
@@ -346,6 +413,7 @@ bdb_idl_fetch_key(
                }
                data.size = BDB_IDL_SIZEOF(ids);
        }
+
        rc2 = cursor->c_close( cursor );
        if (rc2) {
 #ifdef NEW_LOGGING
@@ -358,6 +426,7 @@ bdb_idl_fetch_key(
 #endif
                return rc2;
        }
+
        if( rc == DB_NOTFOUND ) {
                return rc;
 
@@ -400,6 +469,45 @@ bdb_idl_fetch_key(
                return -1;
        }
 
+#ifdef SLAP_IDL_CACHE
+       if ( bdb->bi_idl_cache_max_size ) {
+               bdb_idl_cache_entry_t *ee;
+               ee = (bdb_idl_cache_entry_t *) ch_malloc(
+                       sizeof( bdb_idl_cache_entry_t ) );
+               ee->db = db;
+               ee->idl = (ID*) ch_malloc( BDB_IDL_SIZEOF ( ids ) );
+               ee->idl_lru_prev = NULL;
+               ee->idl_lru_next = NULL;
+               BDB_IDL_CPY( ee->idl, ids );
+               ber_dupbv( &ee->kstr, &idl_tmp.kstr );
+               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_mutex );
+               if ( avl_insert( &bdb->bi_idl_tree, (caddr_t) ee,
+                       bdb_idl_entry_cmp, avl_dup_error ))
+               {
+                       ch_free( ee->kstr.bv_val );
+                       ch_free( ee->idl );
+                       ch_free( ee );
+               } else {
+                       IDL_LRU_ADD( bdb, ee );
+                       if ( ++bdb->bi_idl_cache_size > bdb->bi_idl_cache_max_size ) {
+                               int i = 0;
+                               while ( bdb->bi_idl_lru_tail != NULL && i < 10 ) {
+                                       ee = bdb->bi_idl_lru_tail;
+                                       avl_delete( &bdb->bi_idl_tree, (caddr_t) ee,
+                                                   bdb_idl_entry_cmp );
+                                       IDL_LRU_DELETE( bdb, ee );
+                                       i++;
+                                       --bdb->bi_idl_cache_size;
+                                       ch_free( ee->kstr.bv_val );
+                                       ch_free( ee->idl );
+                                       ch_free( ee );
+                               }
+                       }
+               }
+               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+       }
+#endif
+
        return rc;
 }
 
@@ -434,6 +542,27 @@ bdb_idl_insert_key(
 
        assert( id != NOID );
 
+#ifdef SLAP_IDL_CACHE
+       if ( bdb->bi_idl_cache_size ) {
+               bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp;
+               DBT2bv( key, &idl_tmp.kstr );
+               idl_tmp.db = db;
+               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_mutex );
+               matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+                                             bdb_idl_entry_cmp );
+               if ( matched_idl_entry != NULL ) {
+                       avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry,
+                                   bdb_idl_entry_cmp );
+                       --bdb->bi_idl_cache_size;
+                       IDL_LRU_DELETE( bdb, matched_idl_entry );
+                       free( matched_idl_entry->kstr.bv_val );
+                       free( matched_idl_entry->idl );
+                       free( matched_idl_entry );
+               }
+               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+       }
+#endif
+
        DBTzero( &data );
        data.size = sizeof( ID );
        data.ulen = data.size;
@@ -625,6 +754,27 @@ bdb_idl_delete_key(
        }
        assert( id != NOID );
 
+#ifdef SLAP_IDL_CACHE
+       if ( bdb->bi_idl_cache_max_size ) {
+               bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp;
+               DBT2bv( key, &idl_tmp.kstr );
+               idl_tmp.db = db;
+               ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_mutex );
+               matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+                                             bdb_idl_entry_cmp );
+               if ( matched_idl_entry != NULL ) {
+                       avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry,
+                                   bdb_idl_entry_cmp );
+                       --bdb->bi_idl_cache_size;
+                       IDL_LRU_DELETE( bdb, matched_idl_entry );
+                       free( matched_idl_entry->kstr.bv_val );
+                       free( matched_idl_entry->idl );
+                       free( matched_idl_entry );
+               }
+               ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+       }
+#endif
+
        DBTzero( &data );
        data.data = &tmp;
        data.size = sizeof( id );
@@ -1007,3 +1157,4 @@ ID bdb_idl_next( ID *ids, ID *cursor )
 
        return NOID;
 }
+
index 5a7b2a49b0fb135bc0a8c56ba5c58d6b0b92400f..dd695783df4706b21da174eaaa3087e693f7bb5a 100644 (file)
@@ -1,7 +1,7 @@
 /* index.c - routines for dealing with attribute indexes */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -36,14 +36,14 @@ static slap_mask_t index_mask(
                return mask;
        }
 
-       /* If there is a language tag, did we ever index the base
+       /* If there is a tagging option, did we ever index the base
         * type? If so, check for mask, otherwise it's not there.
         */
-       if( slap_ad_is_lang( desc ) && desc != desc->ad_type->sat_ad ) {
-               /* has language tag */
+       if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) {
+               /* has tagging option */
                bdb_attr_mask( be->be_private, desc->ad_type->sat_ad, &mask );
 
-               if ( mask && ( mask ^ SLAP_INDEX_NOLANG ) ) {
+               if ( mask && ( mask ^ SLAP_INDEX_NOTAGS ) ) {
                        *atname = desc->ad_type->sat_cname;
                        *dbname = desc->ad_type->sat_cname.bv_val;
                        return mask;
@@ -262,7 +262,7 @@ static int index_at_values(
        Backend *be,
        DB_TXN *txn,
        AttributeType *type,
-       struct berval *lang,
+       struct berval *tags,
        BerVarray vals,
        ID id,
        int op )
@@ -273,7 +273,7 @@ static int index_at_values(
        if( type->sat_sup ) {
                /* recurse */
                rc = index_at_values( be, txn,
-                       type->sat_sup, lang,
+                       type->sat_sup, tags,
                        vals, id, op );
 
                if( rc ) return rc;
@@ -293,12 +293,12 @@ static int index_at_values(
                if( rc ) return rc;
        }
 
-       if( lang->bv_len ) {
+       if( tags->bv_len ) {
                AttributeDescription *desc;
 
                mask = 0;
 
-               desc = ad_find_lang( type, lang );
+               desc = ad_find_tags( type, tags );
                if( desc ) {
                        bdb_attr_mask( be->be_private, desc, &mask );
                }
@@ -329,7 +329,7 @@ int bdb_index_values(
        int rc;
 
        rc = index_at_values( be, txn,
-               desc->ad_type, &desc->ad_lang,
+               desc->ad_type, &desc->ad_tags,
                vals, id, op );
 
        return rc;
index ca3bc0501f6dbd7c4d02f77b957cc4c75e19a7c9..91d81b7a2a2d8b916ea3d6e32539b12fb5d7806d 100644 (file)
@@ -1,7 +1,7 @@
 /* init.c - initialize bdb backend */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -95,7 +95,7 @@ bdb_db_init( BackendDB *be )
        bdb->bi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
        bdb->bi_search_stack = NULL;
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        LDAP_LIST_INIT (&bdb->psearch_list);
 #endif
 
@@ -126,7 +126,7 @@ bdb_bt_compare(
        c = curkey->data;
 
 #ifdef WORDS_BIGENDIAN
-       for( i = 0; i < sizeof(ID); i++)
+       for( i = 0; i < (int)sizeof(ID); i++)
 #else
        for( i = sizeof(ID)-1; i >= 0; i--)
 #endif
@@ -157,6 +157,18 @@ bdb_db_open( BackendDB *be )
                be->be_suffix[0].bv_val, 0, 0 );
 #endif
 
+#ifndef BDB_MULTIPLE_SUFFIXES
+       if ( be->be_suffix[1].bv_val ) {
+#ifdef NEW_LOGGING
+       LDAP_LOG( BACK_BDB, ARGS, 
+               "bdb_db_open: only one suffix allowed\n", 0, 0, 0 );
+#else
+       Debug( LDAP_DEBUG_ARGS,
+               "bdb_db_open: only one suffix allowed\n", 0, 0, 0 );
+#endif
+               return -1;
+       }
+#endif
        /* we should check existance of dbenv_home and db_directory */
 
        rc = db_env_create( &bdb->bi_dbenv, 0 );
@@ -522,14 +534,13 @@ bdb_initialize(
 {
        static char *controls[] = {
                LDAP_CONTROL_MANAGEDSAIT,
-#ifdef LDAP_CONTROL_SUBENTRIES
-               LDAP_CONTROL_SUBENTRIES,
-#endif
-#ifdef LDAP_CONTROL_NOOP
                LDAP_CONTROL_NOOP,
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+               LDAP_CONTROL_PAGEDRESULTS,
 #endif
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
                LDAP_CONTROL_VALUESRETURNFILTER,
+#ifdef LDAP_CONTROL_SUBENTRIES
+               LDAP_CONTROL_SUBENTRIES,
 #endif
 #ifdef LDAP_CLIENT_UPDATE
                LDAP_CONTROL_CLIENT_UPDATE,
@@ -642,9 +653,7 @@ bdb_initialize(
 
        bi->bi_chk_referrals = bdb_referrals;
        bi->bi_operational = bdb_operational;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
        bi->bi_has_subordinates = bdb_hasSubordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
        bi->bi_entry_release_rw = bdb_entry_release;
 
        /*
diff --git a/servers/slapd/back-bdb/lcup.c b/servers/slapd/back-bdb/lcup.c
deleted file mode 100644 (file)
index f6481f3..0000000
+++ /dev/null
@@ -1,1053 +0,0 @@
-/* lcup.c - lcup operations */
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "back-bdb.h"
-#include "idl.h"
-#include "external.h"
-
-#ifdef LDAP_CLIENT_UPDATE
-
-static int psearch_base_candidate(
-       BackendDB       *be,
-       Entry   *e,
-       ID              *ids );
-static int psearch_candidates(
-       BackendDB *be,
-       Operation *op,
-       Entry *e,
-       Filter *filter,
-       int scope,
-       int deref,
-       ID      *ids );
-
-int
-bdb_abandon(
-       BackendDB       *be,
-       Connection      *conn,
-       ber_int_t       id )
-{
-       Operation       *ps_list;
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
-       LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
-               if ( ps_list->o_connid == conn->c_connid ) {
-                       if ( ps_list->o_msgid == id ) {
-                               ps_list->o_abandon = 1;
-                               LDAP_LIST_REMOVE( ps_list, link );
-                               slap_op_free ( ps_list );
-                               return LDAP_SUCCESS;
-                       }
-               }
-       }
-       return LDAP_UNAVAILABLE;
-}
-
-int
-bdb_add_psearch_spec(
-       BackendDB       *be,
-       Connection      *conn,
-       Operation       *op,
-       struct berval   *base,
-       struct berval   *nbase,
-       int             scope,
-       int             deref,
-       int             slimit,
-       int             tlimit,
-       Filter          *filter,
-       struct berval   *fstr,
-       AttributeName   *attrs,
-       int             attrsonly )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
-       LDAP_LIST_FIRST(&op->psearch_spec) = (struct lcup_search_spec *)
-               calloc ( 1, sizeof ( struct lcup_search_spec ) );
-
-       LDAP_LIST_FIRST(&op->psearch_spec)->op = op;
-
-       LDAP_LIST_FIRST(&op->psearch_spec)->base = ber_dupbv(NULL, base);
-       LDAP_LIST_FIRST(&op->psearch_spec)->nbase = ber_dupbv(NULL, nbase);
-
-       LDAP_LIST_FIRST(&op->psearch_spec)->scope = scope;
-       LDAP_LIST_FIRST(&op->psearch_spec)->deref = deref;
-       LDAP_LIST_FIRST(&op->psearch_spec)->slimit = slimit;
-       LDAP_LIST_FIRST(&op->psearch_spec)->tlimit = tlimit;
-
-       LDAP_LIST_FIRST(&op->psearch_spec)->filter = filter;
-       LDAP_LIST_FIRST(&op->psearch_spec)->filterstr = ber_dupbv(NULL, fstr);
-       LDAP_LIST_FIRST(&op->psearch_spec)->attrs = attrs;
-
-       LDAP_LIST_FIRST(&op->psearch_spec)->attrsonly = attrsonly;
-
-       LDAP_LIST_FIRST(&op->psearch_spec)->entry_count = 0;
-
-       LDAP_LIST_INSERT_HEAD( &bdb->psearch_list, op, link );
-}
-
-int
-bdb_psearch(
-       BackendDB       *be,
-       Connection      *conn,
-       Operation       *op,
-       Operation       *ps_op,
-       Entry           *entry,
-       int             psearch_type )
-{
-       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       int             rc;
-       const char *text = NULL;
-       time_t          stoptime;
-       unsigned        cursor;
-       ID              id;
-       ID              candidates[BDB_IDL_UM_SIZE];
-       Entry           *e = NULL;
-       BerVarray v2refs = NULL;
-       Entry   *matched = NULL;
-       struct berval   realbase = { 0, NULL };
-       int             nentries = 0;
-       int             manageDSAit;
-
-       Filter lcupf, csnfnot, csnfeq, csnfand, csnfge;
-       AttributeAssertion aa_ge, aa_eq;
-       struct berval entrycsn_bv = { 0, NULL };
-       struct berval latest_entrycsn_bv = { 0, NULL };
-
-       struct slap_limits_set *limit = NULL;
-       int isroot = 0;
-       int scopeok = 0;
-
-       u_int32_t       locker;
-       DB_LOCK         lock;
-
-       Connection      *ps_conn   = ps_op->o_conn;
-       struct berval   *base      = LDAP_LIST_FIRST(&ps_op->psearch_spec)->base;
-       struct berval   *nbase     = LDAP_LIST_FIRST(&ps_op->psearch_spec)->nbase;
-       int             scope      = LDAP_LIST_FIRST(&ps_op->psearch_spec)->scope;
-       int             deref      = LDAP_LIST_FIRST(&ps_op->psearch_spec)->deref;
-       int             slimit     = LDAP_LIST_FIRST(&ps_op->psearch_spec)->slimit;
-       int             tlimit     = LDAP_LIST_FIRST(&ps_op->psearch_spec)->tlimit;
-       Filter          *filter    = LDAP_LIST_FIRST(&ps_op->psearch_spec)->filter;
-       struct berval *filterstr = LDAP_LIST_FIRST(&ps_op->psearch_spec)->filterstr;
-       int             attrsonly  = LDAP_LIST_FIRST(&ps_op->psearch_spec)->attrsonly;
-       AttributeName   uuid_attr[2];
-       AttributeName   *attrs = uuid_attr;
-
-       if ( psearch_type != LCUP_PSEARCH_BY_DELETE &&
-               psearch_type != LCUP_PSEARCH_BY_SCOPEOUT )
-       {
-               attrs = LDAP_LIST_FIRST(&ps_op->psearch_spec)->attrs;
-       } else {
-               attrs[0].an_desc = slap_schema.si_ad_entryUUID;
-               attrs[0].an_oc = NULL;
-               ber_dupbv( &attrs[0].an_name, &attrs[0].an_desc->ad_cname );
-               attrs[1].an_desc = NULL;
-               attrs[1].an_oc = NULL;
-               attrs[1].an_name.bv_len = 0;
-               attrs[1].an_name.bv_val = NULL;
-       }
-
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 );
-#else
-       Debug( LDAP_DEBUG_TRACE, "=> bdb_back_search\n",
-               0, 0, 0);
-#endif
-
-       manageDSAit = get_manageDSAit( ps_op );
-
-       rc = LOCK_ID (bdb->bi_dbenv, &locker );
-       switch(rc) {
-       case 0:
-               break;
-       default:
-               send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
-                       NULL, "internal error", NULL, NULL );
-               if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
-                    psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
-                       ch_free( attrs[0].an_name.bv_val );
-               return rc;
-       }
-
-       if ( nbase->bv_len == 0 ) {
-               /* DIT root special case */
-               e = (Entry *) &slap_entry_root;
-               rc = 0;
-       } else                                          
-#ifdef BDB_ALIASES
-       /* get entry with reader lock */
-       if ( deref & LDAP_DEREF_FINDING ) {
-               e = deref_dn_r( be, nbase-, &err, &matched, &text );
-
-       } else
-#endif
-       {
-dn2entry_retry:
-               rc = bdb_dn2entry_r( be, NULL, nbase, &e, &matched, 0, locker, &lock );
-       }
-
-       switch(rc) {
-       case DB_NOTFOUND:
-       case 0:
-               break;
-       case LDAP_BUSY:
-               if (e != NULL) {
-                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
-                               e, &lock);
-               }
-               if (matched != NULL) {
-                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
-                               matched, &lock);
-               }
-               send_ldap_result( ps_conn, ps_op, LDAP_BUSY,
-                       NULL, "ldap server busy", NULL, NULL );
-               LOCK_ID_FREE( bdb->bi_dbenv, locker );
-               if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
-                    psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
-                       ch_free( attrs[0].an_name.bv_val );
-               return LDAP_BUSY;
-       case DB_LOCK_DEADLOCK:
-       case DB_LOCK_NOTGRANTED:
-               goto dn2entry_retry;
-       default:
-               if (e != NULL) {
-                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
-                               e, &lock);
-               }
-               if (matched != NULL) {
-                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
-                               matched, &lock);
-               }
-               send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
-                       NULL, "internal error", NULL, NULL );
-               LOCK_ID_FREE( bdb->bi_dbenv, locker );
-               if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
-                    psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
-                       ch_free( attrs[0].an_name.bv_val );
-               return rc;
-       }
-
-       if ( e == NULL ) {
-               struct berval matched_dn = { 0, NULL };
-               BerVarray refs = NULL;
-
-               if ( matched != NULL ) {
-                       BerVarray erefs;
-                       ber_dupbv( &matched_dn, &matched->e_name );
-
-                       erefs = is_entry_referral( matched )
-                               ? get_entry_referrals( be, ps_conn, ps_op, matched )
-                               : NULL;
-
-                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
-                               matched, &lock);
-                       matched = NULL;
-
-                       if( erefs ) {
-                               refs = referral_rewrite( erefs, &matched_dn,
-                                       base, scope );
-                               ber_bvarray_free( erefs );
-                       }
-
-               } else {
-                       refs = referral_rewrite( default_referral,
-                               NULL, base, scope );
-               }
-
-               send_ldap_result( ps_conn, ps_op,       rc=LDAP_REFERRAL ,
-                       matched_dn.bv_val, text, refs, NULL );
-
-               LOCK_ID_FREE( bdb->bi_dbenv, locker );
-               if ( refs ) ber_bvarray_free( refs );
-               if ( matched_dn.bv_val ) ber_memfree( matched_dn.bv_val );
-               if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
-                    psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
-                       ch_free( attrs[0].an_name.bv_val );
-               return rc;
-       }
-
-       if (!manageDSAit && e != &slap_entry_root && is_entry_referral( e ) ) {
-               /* entry is a referral, don't allow add */
-               struct berval matched_dn;
-               BerVarray erefs, refs;
-               
-               ber_dupbv( &matched_dn, &e->e_name );
-               erefs = get_entry_referrals( be, ps_conn, ps_op, e );
-               refs = NULL;
-
-               bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
-               e = NULL;
-
-               if( erefs ) {
-                       refs = referral_rewrite( erefs, &matched_dn,
-                               base, scope );
-                       ber_bvarray_free( erefs );
-               }
-
-#ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, RESULTS, 
-                       "bdb_search: entry is referral\n", 0, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE, "bdb_search: entry is referral\n",
-                       0, 0, 0 );
-#endif
-
-               send_ldap_result( ps_conn, ps_op, LDAP_REFERRAL,
-                       matched_dn.bv_val,
-                       refs ? NULL : "bad referral object",
-                       refs, NULL );
-
-               LOCK_ID_FREE( bdb->bi_dbenv, locker );
-               ber_bvarray_free( refs );
-               ber_memfree( matched_dn.bv_val );
-               if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
-                    psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
-                       ch_free( attrs[0].an_name.bv_val );
-               return 1;
-       }
-
-       /* if not root, get appropriate limits */
-       if ( be_isroot( be, &ps_op->o_ndn ) ) {
-               isroot = 1;
-       } else {
-               ( void ) get_limits( be, &ps_op->o_ndn, &limit );
-       }
-
-       /* The time/size limits come first because they require very little
-        * effort, so there's no chance the candidates are selected and then 
-        * the request is not honored only because of time/size constraints */
-
-       /* if no time limit requested, use soft limit (unless root!) */
-       if ( isroot ) {
-               if ( tlimit == 0 ) {
-                       tlimit = -1;    /* allow root to set no limit */
-               }
-
-               if ( slimit == 0 ) {
-                       slimit = -1;
-               }
-
-       } else {
-               /* if no limit is required, use soft limit */
-               if ( tlimit <= 0 ) {
-                       tlimit = limit->lms_t_soft;
-
-               /* if requested limit higher than hard limit, abort */
-               } else if ( tlimit > limit->lms_t_hard ) {
-                       /* no hard limit means use soft instead */
-                       if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) {
-                               tlimit = limit->lms_t_soft;
-
-                       /* positive hard limit means abort */
-                       } else if ( limit->lms_t_hard > 0 ) {
-                               send_search_result( ps_conn, ps_op, 
-                                               LDAP_UNWILLING_TO_PERFORM,
-                                               NULL, NULL, NULL, NULL, 0 );
-                               rc = 0;
-                               goto done;
-                       }
-               
-                       /* negative hard limit means no limit */
-               }
-               
-               /* if no limit is required, use soft limit */
-               if ( slimit <= 0 ) {
-                       slimit = limit->lms_s_soft;
-
-               /* if requested limit higher than hard limit, abort */
-               } else if ( slimit > limit->lms_s_hard ) {
-                       /* no hard limit means use soft instead */
-                       if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) {
-                               slimit = limit->lms_s_soft;
-
-                       /* positive hard limit means abort */
-                       } else if ( limit->lms_s_hard > 0 ) {
-                               send_search_result( ps_conn, ps_op, 
-                                               LDAP_UNWILLING_TO_PERFORM,
-                                               NULL, NULL, NULL, NULL, 0 );
-                               rc = 0; 
-                               goto done;
-                       }
-                       
-                       /* negative hard limit means no limit */
-               }
-       }
-
-       /* compute it anyway; root does not use it */
-       stoptime = ps_op->o_time + tlimit;
-
-       /* select candidates */
-       if ( scope == LDAP_SCOPE_BASE ) {
-               rc = psearch_base_candidate( be, e, candidates );
-       } else {
-               BDB_IDL_ALL( bdb, candidates );
-               rc = psearch_candidates( be, op, e, filter,
-                       scope, deref, candidates );
-       }
-
-       if ( !BDB_IDL_IS_RANGE( candidates ) ) {
-               cursor = bdb_idl_search( candidates, entry->e_id );
-               if ( candidates[cursor] != entry->e_id ) {
-                       goto test_done;
-               }
-       } else {
-               if ( entry->e_id < BDB_IDL_RANGE_FIRST(candidates) &&
-                    entry->e_id > BDB_IDL_RANGE_LAST(candidates) )
-               {
-                       goto test_done;
-               }
-       }
-
-       /* candidates = { e } */
-       candidates[0] = 1;
-       candidates[1] = entry->e_id;
-
-       /* need normalized dn below */
-       ber_dupbv( &realbase, &e->e_nname );
-
-       if ( e != &slap_entry_root ) {
-               bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
-       }
-       e = NULL;
-
-       if ( candidates[0] == 0 ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS,
-                       "bdb_search: no candidates\n", 0, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE, "bdb_search: no candidates\n",
-                       0, 0, 0 );
-#endif
-
-               send_search_result( ps_conn, ps_op,
-                       LDAP_SUCCESS,
-                       NULL, NULL, NULL, NULL, 0 );
-
-               rc = 1;
-               goto done;
-       }
-
-       /* if not root and candidates exceed to-be-checked entries, abort */
-       if ( !isroot && limit->lms_s_unchecked != -1 ) {
-               if ( BDB_IDL_N(candidates) > (unsigned) limit->lms_s_unchecked ) {
-                       send_search_result( ps_conn, ps_op, LDAP_ADMINLIMIT_EXCEEDED,
-                               NULL, NULL, NULL, NULL, 0 );
-                       rc = 1;
-                       goto done;
-               }
-       }
-
-       lcupf.f_choice = LDAP_FILTER_AND;
-       lcupf.f_and = &csnfnot;
-       lcupf.f_next = NULL;
-
-       csnfnot.f_choice = LDAP_FILTER_NOT;
-       csnfnot.f_not = &csnfeq;
-       csnfnot.f_next = &csnfand;
-
-       csnfeq.f_choice = LDAP_FILTER_EQUALITY;
-       csnfeq.f_ava = &aa_eq;
-       csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
-       ber_dupbv( &csnfeq.f_av_value, &ps_op->o_clientupdate_state );
-
-       csnfand.f_choice = LDAP_FILTER_AND;
-       csnfand.f_and = &csnfge;
-       csnfand.f_next = NULL;
-
-       csnfge.f_choice = LDAP_FILTER_GE;
-       csnfge.f_ava = &aa_ge;
-       csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
-       ber_dupbv( &csnfge.f_av_value, &ps_op->o_clientupdate_state );
-       csnfge.f_next = filter;
-
-       id = entry->e_id;
-
-       /* check for abandon */
-       if ( ps_op->o_abandon ) {
-               rc = 0;
-               goto done;
-       }
-
-       /* check time limit */
-       if ( tlimit != -1 && slap_get_time() > stoptime ) {
-               send_search_result( ps_conn, ps_op, rc = LDAP_TIMELIMIT_EXCEEDED,
-                       NULL, NULL, v2refs, NULL, nentries );
-               goto done;
-       }
-
-       e = entry;
-
-#ifdef BDB_SUBENTRIES
-       if ( is_entry_subentry( e ) ) {
-               if( scope != LDAP_SCOPE_BASE ) {
-                       if(!get_subentries_visibility( ps_op )) {
-                               /* only subentries are visible */
-                               goto test_done;
-                       }
-
-               } else if ( get_subentries( ps_op ) &&
-                       !get_subentries_visibility( ps_op ))
-               {
-                       /* only subentries are visible */
-                       goto test_done;
-               }
-
-       } else if ( get_subentries_visibility( ps_op )) {
-               /* only subentries are visible */
-               goto test_done;
-       }
-#endif
-
-#ifdef BDB_ALIASES
-       if ( deref & LDAP_DEREF_SEARCHING && is_entry_alias( e ) ) {
-               Entry *matched;
-               int err;
-               const char *text;
-               
-               e = deref_entry_r( be, e, &err, &matched, &text );
-
-               if( e == NULL ) {
-                       e = matched;
-                       goto test_done;
-               }
-
-               if( e->e_id == id ) {
-                       /* circular loop */
-                       goto test_done;
-               }
-
-               /* need to skip alias which deref into scope */
-               if( scope & LDAP_SCOPE_ONELEVEL ) {
-                       struct berval   pdn;
-                       
-                       dnParent( &e->e_nname, &pdn ):
-                       if ( ber_bvcmp( pdn, &realbase ) ) {
-                               goto test_done;
-                       }
-
-               } else if ( dnIsSuffix( &e->e_nname, &realbase ) ) {
-                       /* alias is within scope */
-#ifdef NEW_LOGGING
-                       LDAP_LOG ( OPERATION, RESULTS,
-                               "bdb_search: \"%s\" in subtree\n", e->edn, 0, 0);
-#else
-                       Debug( LDAP_DEBUG_TRACE,
-                               "bdb_search: \"%s\" in subtree\n",
-                               e->e_dn, 0, 0 );
-#endif
-                       goto test_done;
-               }
-
-               scopeok = 1;
-       }
-#endif
-
-       /*
-        * if it's a referral, add it to the list of referrals. only do
-        * this for non-base searches, and don't check the filter
-        * explicitly here since it's only a candidate anyway.
-        */
-       if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
-               is_entry_referral( e ) )
-       {
-               struct berval   dn;
-
-               /* check scope */
-               if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
-                       if ( !be_issuffix( be, &e->e_nname ) ) {
-                               dnParent( &e->e_nname, &dn );
-                               scopeok = dn_match( &dn, &realbase );
-                       } else {
-                               scopeok = (realbase.bv_len == 0);
-                       }
-
-               } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
-                       scopeok = dnIsSuffix( &e->e_nname, &realbase );
-
-               } else {
-                       scopeok = 1;
-               }
-
-               if( scopeok ) {
-                       BerVarray erefs = get_entry_referrals(
-                               be, ps_conn, ps_op, e );
-                       BerVarray refs = referral_rewrite( erefs,
-                               &e->e_name, NULL,
-                               scope == LDAP_SCOPE_SUBTREE
-                                       ? LDAP_SCOPE_SUBTREE
-                                       : LDAP_SCOPE_BASE );
-
-                       send_search_reference( be, ps_conn, ps_op,
-                               e, refs, NULL, &v2refs );
-
-                       ber_bvarray_free( refs );
-
-               } else {
-#ifdef NEW_LOGGING
-                       LDAP_LOG(OPERATION, DETAIL2, 
-                               "bdb_search: candidate referral %ld scope not okay\n",
-                               id, 0, 0 );
-#else
-                       Debug( LDAP_DEBUG_TRACE,
-                               "bdb_search: candidate referral %ld scope not okay\n",
-                               id, 0, 0 );
-#endif
-               }
-
-               goto test_done;
-       }
-
-       if ( psearch_type != LCUP_PSEARCH_BY_SCOPEOUT ) {
-               rc = test_filter( be, ps_conn, ps_op, e, &lcupf );
-       } else {
-               rc = LDAP_COMPARE_TRUE;
-       }
-
-       if ( rc == LDAP_COMPARE_TRUE ) {
-               struct berval   dn;
-
-               /* check scope */
-               if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
-                       if ( be_issuffix( be, &e->e_nname ) ) {
-                               scopeok = (realbase.bv_len == 0);
-                       } else {
-                               dnParent( &e->e_nname, &dn );
-                               scopeok = dn_match( &dn, &realbase );
-                       }
-
-               } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
-                       scopeok = dnIsSuffix( &e->e_nname, &realbase );
-
-               } else {
-                       scopeok = 1;
-               }
-
-               if ( scopeok ) {
-                       /* check size limit */
-                       if ( --slimit == -1 ) {
-                               send_search_result( ps_conn, ps_op,
-                                       rc = LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
-                                       v2refs, NULL, nentries );
-                               goto done;
-                       }
-
-                       if (e) {
-                               int result;
-                               
-#if 0  /* noop is masked SLAP_CTRL_UPDATE */
-                               if( ps_op->o_noop ) {
-                                       result = 0;
-                               } else
-#endif
-                               {
-                                       if ( psearch_type == LCUP_PSEARCH_BY_ADD ||
-                                            psearch_type == LCUP_PSEARCH_BY_DELETE ||
-                                            psearch_type == LCUP_PSEARCH_BY_MODIFY ||
-                                            psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
-                                       {
-                                               Attribute* a;
-                                               int ret;
-                                               int res;
-                                               const char *text = NULL;
-                                               LDAPControl *ctrls[2];
-                                               struct berval *bv;
-
-                                               BerElement *ber = ber_alloc_t( LBER_USE_DER );
-
-                                               if ( ber == NULL ) {
-#ifdef NEW_LOGGING
-                                                       LDAP_LOG ( OPERATION, RESULTS, 
-                                                               "bdb_search: ber_alloc_t failed\n",
-                                                               0, 0, 0 );
-#else
-                                                       Debug( LDAP_DEBUG_TRACE,
-                                                               "bdb_search: ber_alloc_t failed\n",
-                                                               0, 0, 0 );
-#endif
-                                                       send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
-                                                               NULL, "internal error", NULL, NULL );
-                                                       goto done;
-                                               }
-
-                                               LDAP_LIST_FIRST(&ps_op->psearch_spec)->entry_count++;
-
-                                               ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) );
-                                               ctrls[1] = NULL;
-
-                                               if ( LDAP_LIST_FIRST(
-                                                       &ps_op->psearch_spec)->entry_count %
-                                                               ps_op->o_clientupdate_interval == 0 )
-                                               {
-                                                       /* Send cookie */
-                                                       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-                                                               AttributeDescription *desc = a->a_desc;
-                                                               if ( desc == slap_schema.si_ad_entryCSN ) {
-                                                                       ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
-                                                                       if ( latest_entrycsn_bv.bv_val == NULL ) {
-                                                                               ber_dupbv( &latest_entrycsn_bv,
-                                                                                       &entrycsn_bv );
-                                                                       } else {
-                                                                               res = value_match( &ret, desc,
-                                                                                       desc->ad_type->sat_ordering,
-                                                                                       SLAP_MR_ASSERTION_SYNTAX_MATCH,
-                                                                                       &entrycsn_bv, &latest_entrycsn_bv,
-                                                                                       &text );
-                                                                               if ( res != LDAP_SUCCESS ) {
-                                                                                       ret = 0;
-#ifdef NEW_LOGGING
-                                                                                       LDAP_LOG ( OPERATION, RESULTS, 
-                                                                                               "bdb_search: "
-                                                                                               "value_match failed\n",
-                                                                                               0, 0, 0 );
-#else
-                                                                                       Debug( LDAP_DEBUG_TRACE,
-                                                                                               "bdb_search: "
-                                                                                               "value_match failed\n",
-                                                                                               0, 0, 0 );
-#endif
-                                                                               }
-
-                                                                               if ( ret > 0 ) {
-                                                                                       ch_free(latest_entrycsn_bv.bv_val);
-                                                                                       latest_entrycsn_bv.bv_val = NULL;
-                                                                                       ber_dupbv( &latest_entrycsn_bv,
-                                                                                               &entrycsn_bv );
-                                                                               }
-                                                                       }
-                                                               }
-                                                       }
-
-                                                       if ( psearch_type != LCUP_PSEARCH_BY_DELETE ||
-                                                               psearch_type != LCUP_PSEARCH_BY_SCOPEOUT )
-                                                       {
-                                                               ber_printf( ber, "{bb{sON}N}",
-                                                                       SLAP_LCUP_STATE_UPDATE_FALSE,
-                                                                       SLAP_LCUP_ENTRY_DELETED_FALSE,
-                                                                       LCUP_COOKIE_OID, &entrycsn_bv );
-                                                       } else {
-                                                               ber_printf( ber, "{bb{sON}N}",
-                                                                       SLAP_LCUP_STATE_UPDATE_FALSE,
-                                                                       SLAP_LCUP_ENTRY_DELETED_TRUE,
-                                                                       LCUP_COOKIE_OID, &entrycsn_bv );
-                                                       }
-
-                                                       ch_free( entrycsn_bv.bv_val );
-                                                       entrycsn_bv.bv_val = NULL;
-
-                                               } else {
-                                                       /* Do not send cookie */
-                                                       if ( psearch_type != LCUP_PSEARCH_BY_DELETE ||
-                                                               psearch_type != LCUP_PSEARCH_BY_SCOPEOUT )
-                                                       {
-                                                               ber_printf( ber, "{bbN}",
-                                                                       SLAP_LCUP_STATE_UPDATE_FALSE,
-                                                                       SLAP_LCUP_ENTRY_DELETED_FALSE );
-                                                       } else {
-                                                               ber_printf( ber, "{bbN}",
-                                                                       SLAP_LCUP_STATE_UPDATE_FALSE,
-                                                                       SLAP_LCUP_ENTRY_DELETED_TRUE );
-                                                       }
-                                               }
-
-                                               ctrls[0]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE;
-                                               ctrls[0]->ldctl_iscritical = ps_op->o_clientupdate;
-                                               ret = ber_flatten( ber, &bv );
-
-                                               if ( ret < 0 ) {
-#ifdef NEW_LOGGING
-                                                       LDAP_LOG ( OPERATION, RESULTS, 
-                                                               "bdb_search: ber_flatten failed\n",
-                                                               0, 0, 0 );
-#else
-                                                       Debug( LDAP_DEBUG_TRACE,
-                                                               "bdb_search: ber_flatten failed\n",
-                                                               0, 0, 0 );
-#endif
-                                                       send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
-                                                               NULL, "internal error", NULL, NULL );
-                                                       goto done;
-                                               }
-
-                                               ber_dupbv( &ctrls[0]->ldctl_value, bv );
-                                               
-                                               result = send_search_entry( be, ps_conn, ps_op,
-                                                       e, attrs, attrsonly, ctrls);
-
-                                               ch_free( ctrls[0]->ldctl_value.bv_val );
-                                               ch_free( ctrls[0] );
-                                               ber_free( ber, 1 );
-                                               ber_bvfree( bv );
-
-                                               if ( psearch_type == LCUP_PSEARCH_BY_MODIFY ) {
-                                                       struct psid_entry* psid_e;
-                                                       LDAP_LIST_FOREACH( psid_e, &op->premodify_list,
-                                                               link)
-                                                       {
-                                                               if( psid_e->ps ==
-                                                                       LDAP_LIST_FIRST(&ps_op->psearch_spec))
-                                                               {
-                                                                       LDAP_LIST_REMOVE(psid_e, link);
-                                                                       break;
-                                                               }
-                                                       }
-                                                       if (psid_e != NULL) free (psid_e);
-                                               }
-
-                                       } else if ( psearch_type == LCUP_PSEARCH_BY_PREMODIFY ) {
-                                               struct psid_entry* psid_e;
-                                               psid_e = (struct psid_entry *) calloc (1,
-                                                       sizeof(struct psid_entry));
-                                               psid_e->ps = LDAP_LIST_FIRST(&ps_op->psearch_spec);
-                                               LDAP_LIST_INSERT_HEAD( &op->premodify_list,
-                                                       psid_e, link );
-
-                                       } else {
-                                               printf("Error !\n");
-                                       }
-                               }
-
-                               switch (result) {
-                               case 0:         /* entry sent ok */
-                                       nentries++;
-                                       break;
-                               case 1:         /* entry not sent */
-                                       break;
-                               case -1:        /* connection closed */
-                                       rc = LDAP_OTHER;
-                                       goto done;
-                               }
-                       }
-               } else {
-#ifdef NEW_LOGGING
-                       LDAP_LOG ( OPERATION, RESULTS,
-                               "bdb_search: %ld scope not okay\n", (long) id, 0, 0);
-#else
-                       Debug( LDAP_DEBUG_TRACE,
-                               "bdb_search: %ld scope not okay\n", (long) id, 0, 0 );
-#endif
-               }
-       } else {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS,
-                       "bdb_search: %ld does match filter\n", (long) id, 0, 0);
-#else
-               Debug( LDAP_DEBUG_TRACE,
-                       "bdb_search: %ld does match filter\n",
-                       (long) id, 0, 0 );
-#endif
-       }
-
-test_done:
-       rc = LDAP_SUCCESS;
-
-done:
-       if ( csnfeq.f_ava != NULL && csnfeq.f_av_value.bv_val != NULL ) {
-               ch_free( csnfeq.f_av_value.bv_val );
-       }
-
-       if ( csnfge.f_ava != NULL && csnfge.f_av_value.bv_val != NULL ) {
-               ch_free( csnfge.f_av_value.bv_val );
-       }
-
-       LOCK_ID_FREE( bdb->bi_dbenv, locker );
-
-       if( v2refs ) ber_bvarray_free( v2refs );
-       if( realbase.bv_val ) ch_free( realbase.bv_val );
-       if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
-            psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
-               ch_free( attrs[0].an_name.bv_val );
-
-       return rc;
-}
-
-static int psearch_base_candidate(
-       BackendDB       *be,
-       Entry   *e,
-       ID              *ids )
-{
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY,
-               "psearch_base_candidate: base: \"%s\" (0x%08lx)\n", e->e_dn, (long) e->e_id, 0);
-#else
-       Debug(LDAP_DEBUG_ARGS, "psearch_base_candidates: base: \"%s\" (0x%08lx)\n",
-               e->e_dn, (long) e->e_id, 0);
-#endif
-
-       ids[0] = 1;
-       ids[1] = e->e_id;
-       return 0;
-}
-
-/* Look for "objectClass Present" in this filter.
- * Also count depth of filter tree while we're at it.
- */
-static int psearch_oc_filter(
-       Filter *f,
-       int cur,
-       int *max
-)
-{
-       int rc = 0;
-
-       if( cur > *max ) *max = cur;
-
-       switch(f->f_choice) {
-       case LDAP_FILTER_PRESENT:
-               if (f->f_desc == slap_schema.si_ad_objectClass) {
-                       rc = 1;
-               }
-               break;
-
-       case LDAP_FILTER_AND:
-       case LDAP_FILTER_OR:
-               cur++;
-               for (f=f->f_and; f; f=f->f_next) {
-                       (void) psearch_oc_filter(f, cur, max);
-               }
-               break;
-
-       default:
-               break;
-       }
-       return rc;
-}
-
-static int psearch_candidates(
-       BackendDB *be,
-       Operation *op,
-       Entry *e,
-       Filter *filter,
-       int scope,
-       int deref,
-       ID      *ids )
-{
-       int rc, depth = 1;
-       Filter          f, scopef, rf, xf;
-       ID              *stack;
-       AttributeAssertion aa_ref;
-#ifdef BDB_SUBENTRIES
-       Filter  sf;
-       AttributeAssertion aa_subentry;
-#endif
-#ifdef BDB_ALIASES
-       Filter  af;
-       AttributeAssertion aa_alias;
-#endif
-
-       /*
-        * This routine takes as input a filter (user-filter)
-        * and rewrites it as follows:
-        *      (&(scope=DN)[(objectClass=subentry)]
-        *              (|[(objectClass=referral)(objectClass=alias)](user-filter))
-        */
-
-#ifdef NEW_LOGGING
-       LDAP_LOG ( OPERATION, ENTRY,
-               "psearch_candidates: base=\"%s\" (0x%08lx) scope=%d\n", 
-               e->e_dn, (long) e->e_id, scope);
-#else
-       Debug(LDAP_DEBUG_TRACE,
-               "psearch_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
-               e->e_dn, (long) e->e_id, scope );
-#endif
-
-       xf.f_or = filter;
-       xf.f_choice = LDAP_FILTER_OR;
-       xf.f_next = NULL;
-
-       /* If the user's filter uses objectClass=*,
-        * these clauses are redundant.
-        */
-       if (!psearch_oc_filter(filter, 1, &depth) && !get_subentries_visibility(op) ) {
-               if( !get_manageDSAit(op) ) { /* match referrals */
-                       struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" };
-                       rf.f_choice = LDAP_FILTER_EQUALITY;
-                       rf.f_ava = &aa_ref;
-                       rf.f_av_desc = slap_schema.si_ad_objectClass;
-                       rf.f_av_value = bv_ref;
-                       rf.f_next = xf.f_or;
-                       xf.f_or = &rf;
-               }
-
-#ifdef BDB_ALIASES
-               if( deref & LDAP_DEREF_SEARCHING ) { /* match aliases */
-                       struct berval bv_alias = { sizeof("ALIAS")-1, "ALIAS" };
-                       af.f_choice = LDAP_FILTER_EQUALITY;
-                       af.f_ava = &aa_alias;
-                       af.f_av_desc = slap_schema.si_ad_objectClass;
-                       af.f_av_value = bv_alias;
-                       af.f_next = xf.f_or;
-                       xf.f_or = &af;
-               }
-#endif
-               /* We added one of these clauses, filter depth increased */
-               if( xf.f_or != filter ) depth++;
-       }
-
-       f.f_next = NULL;
-       f.f_choice = LDAP_FILTER_AND;
-       f.f_and = &scopef;
-       scopef.f_choice = scope == LDAP_SCOPE_SUBTREE
-               ? SLAPD_FILTER_DN_SUBTREE
-               : SLAPD_FILTER_DN_ONE;
-       scopef.f_dn = &e->e_nname;
-       scopef.f_next = xf.f_or == filter ? filter : &xf ;
-       /* Filter depth increased again, adding scope clause */
-       depth++;
-
-#ifdef BDB_SUBENTRIES
-       if( get_subentries_visibility( op ) ) {
-               struct berval bv_subentry = { sizeof("SUBENTRY")-1, "SUBENTRY" };
-               sf.f_choice = LDAP_FILTER_EQUALITY;
-               sf.f_ava = &aa_subentry;
-               sf.f_av_desc = slap_schema.si_ad_objectClass;
-               sf.f_av_value = bv_subentry;
-               sf.f_next = scopef.f_next;
-               scopef.f_next = &sf;
-       }
-#endif
-
-       /* Allocate IDL stack, plus 1 more for former tmp */
-       stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
-
-       rc = bdb_filter_candidates( be, &f, ids, stack, stack+BDB_IDL_UM_SIZE );
-
-       ch_free( stack );
-
-       if( rc ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, DETAIL1,
-                       "bdb_psearch_candidates: failed (rc=%d)\n", rc, 0, 0  );
-#else
-               Debug(LDAP_DEBUG_TRACE,
-                       "bdb_psearch_candidates: failed (rc=%d)\n",
-                       rc, NULL, NULL );
-#endif
-
-       } else {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, DETAIL1,
-                       "bdb_psearch_candidates: id=%ld first=%ld last=%ld\n",
-                       (long) ids[0], (long) BDB_IDL_FIRST(ids), 
-                       (long) BDB_IDL_LAST(ids));
-#else
-               Debug(LDAP_DEBUG_TRACE,
-                       "bdb_psearch_candidates: id=%ld first=%ld last=%ld\n",
-                       (long) ids[0],
-                       (long) BDB_IDL_FIRST(ids),
-                       (long) BDB_IDL_LAST(ids) );
-#endif
-       }
-
-       return rc;
-}
-
-
-#endif /* LDAP_CLIENT_UPDATE */
index 3f267b03131ca2d99a1a3a48dc73f6b6245dd737..3d9e86dcebcfbd9050bf23c78fc02b31faed0f5b 100644 (file)
@@ -1,7 +1,7 @@
 /* modify.c - bdb backend modify routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -56,7 +56,8 @@ int bdb_modify_internal(
 #else
                        Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: add\n", 0, 0, 0);
 #endif
-                       err = modify_add_values( e, mod, text, textbuf, textlen );
+                       err = modify_add_values( e, mod, get_permitmodify(op),
+                               text, textbuf, textlen );
                        if( err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG ( OPERATION, ERR, 
@@ -75,7 +76,8 @@ int bdb_modify_internal(
 #else
                        Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: delete\n", 0, 0, 0);
 #endif
-                       err = modify_delete_values( e, mod, text, textbuf, textlen );
+                       err = modify_delete_values( e, mod, get_permitmodify(op),
+                               text, textbuf, textlen );
                        assert( err != LDAP_TYPE_OR_VALUE_EXISTS );
                        if( err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
@@ -95,7 +97,8 @@ int bdb_modify_internal(
 #else
                        Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: replace\n", 0, 0, 0);
 #endif
-                       err = modify_replace_values( e, mod, text, textbuf, textlen );
+                       err = modify_replace_values( e, mod, get_permitmodify(op),
+                               text, textbuf, textlen );
                        if( err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG ( OPERATION, ERR, 
@@ -119,7 +122,8 @@ int bdb_modify_internal(
                         */
                        mod->sm_op = LDAP_MOD_ADD;
 
-                       err = modify_add_values( e, mod, text, textbuf, textlen );
+                       err = modify_add_values( e, mod, get_permitmodify(op),
+                               text, textbuf, textlen );
                        if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
                                err = LDAP_SUCCESS;
                        }
@@ -272,12 +276,12 @@ bdb_modify(
        DB_TXN  *ltid = NULL;
        struct bdb_op_info opinfo;
 
-       u_int32_t       locker;
+       u_int32_t       locker = 0;
        DB_LOCK         lock;
 
        int             noop = 0;
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        Operation* ps_list;
        struct psid_entry* pm_list;
        struct psid_entry* pm_prev;
@@ -302,7 +306,7 @@ retry:      /* transaction retry */
                        "bdb_modify: retrying...\n", 0, 0, 0);
 #endif
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
                pm_list = LDAP_LIST_FIRST(&op->premodify_list);
                while ( pm_list != NULL ) {
                        LDAP_LIST_REMOVE ( pm_list, link );
@@ -345,6 +349,7 @@ retry:      /* transaction retry */
 
        opinfo.boi_bdb = be;
        opinfo.boi_txn = ltid;
+       opinfo.boi_locker = locker;
        opinfo.boi_err = 0;
        op->o_private = &opinfo;
 
@@ -423,13 +428,13 @@ retry:    /* transaction retry */
                goto done;
        }
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        if ( rc == LDAP_SUCCESS && !op->o_noop ) {
                LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
-                       bdb_psearch(be, conn, op, ps_list, e, LCUP_PSEARCH_BY_PREMODIFY );
+                       bdb_psearch(be, conn, op, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
                }
        }
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
        
        /* Modify the entry */
        rc = bdb_modify_internal( be, conn, op, ltid, modlist, e,
@@ -518,23 +523,23 @@ return_results:
        send_ldap_result( conn, op, rc,
                NULL, text, NULL, NULL );
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        if ( rc == LDAP_SUCCESS && !op->o_noop ) {
                /* Loop through in-scope entries for each psearch spec */
                LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
-                       bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_MODIFY );
+                       bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
                }
                pm_list = LDAP_LIST_FIRST(&op->premodify_list);
                while ( pm_list != NULL ) {
                        bdb_psearch(be, conn, op, pm_list->ps->op,
-                                               e, LCUP_PSEARCH_BY_SCOPEOUT);
+                                               e, LDAP_PSEARCH_BY_SCOPEOUT);
                        LDAP_LIST_REMOVE ( pm_list, link );
                        pm_prev = pm_list;
                        pm_list = LDAP_LIST_NEXT ( pm_list, link );
                        free (pm_prev);
                }
        }
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
 
        if( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
                ldap_pvt_thread_yield();
@@ -544,7 +549,7 @@ return_results:
 
 done:
        if( ltid != NULL ) {
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
                pm_list = LDAP_LIST_FIRST(&op->premodify_list);
                while ( pm_list != NULL ) {
                        LDAP_LIST_REMOVE ( pm_list, link );
index c7b95a313fe5c9c779ac1205bded6edc5db41055..8fcba26ffd4b93f4c424d95b7229961761aa65d5 100644 (file)
@@ -1,7 +1,7 @@
 /* modrdn.c - bdb backend modrdn routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -57,12 +57,12 @@ bdb_modrdn(
 
        int             manageDSAit = get_manageDSAit( op );
 
-       u_int32_t       locker;
+       u_int32_t       locker = 0;
        DB_LOCK         lock;
 
        int             noop = 0;
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
         Operation* ps_list;
         struct psid_entry* pm_list;
         struct psid_entry* pm_prev;
@@ -95,7 +95,7 @@ retry:        /* transaction retry */
                Debug( LDAP_DEBUG_TRACE, "==>bdb_modrdn: retrying...\n", 0, 0, 0 );
 #endif
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
                 pm_list = LDAP_LIST_FIRST(&op->premodify_list);
                 while ( pm_list != NULL ) {
                         LDAP_LIST_REMOVE ( pm_list, link );
@@ -139,6 +139,7 @@ retry:      /* transaction retry */
 
        opinfo.boi_bdb = be;
        opinfo.boi_txn = ltid;
+       opinfo.boi_locker = locker;
        opinfo.boi_err = 0;
        op->o_private = &opinfo;
 
@@ -731,13 +732,13 @@ retry:    /* transaction retry */
                goto return_results;
        }
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        if ( rc == LDAP_SUCCESS && !op->o_noop ) {
                LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
-                       bdb_psearch(be, conn, op, ps_list, e, LCUP_PSEARCH_BY_PREMODIFY );
+                       bdb_psearch(be, conn, op, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
                }
        }
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
 
        /* modify entry */
        rc = bdb_modify_internal( be, conn, op, ltid, &mod[0], e,
@@ -833,23 +834,23 @@ return_results:
        send_ldap_result( conn, op, rc,
                NULL, text, NULL, NULL );
 
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
        if ( rc == LDAP_SUCCESS && !op->o_noop ) {
                /* Loop through in-scope entries for each psearch spec */
                LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
-                       bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_MODIFY );
+                       bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
                }
                pm_list = LDAP_LIST_FIRST(&op->premodify_list);
                while ( pm_list != NULL ) {
                        bdb_psearch(be, conn, op, pm_list->ps->op,
-                                               e, LCUP_PSEARCH_BY_SCOPEOUT);
+                                               e, LDAP_PSEARCH_BY_SCOPEOUT);
                        LDAP_LIST_REMOVE ( pm_list, link );
                        pm_prev = pm_list;
                        pm_list = LDAP_LIST_NEXT ( pm_list, link );
                         free (pm_prev);
                }
        }
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
 
        if( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
                ldap_pvt_thread_yield();
@@ -893,7 +894,7 @@ done:
        }
 
        if( ltid != NULL ) {
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
                 pm_list = LDAP_LIST_FIRST(&op->premodify_list);
                 while ( pm_list != NULL ) {
                         LDAP_LIST_REMOVE ( pm_list, link );
index 7cead61e7c3d7cb375fcc8d29fba72f2c2087472..ca87a6c7277d8df465513073ab2c3b0d67aa1a41 100644 (file)
@@ -1,6 +1,6 @@
 /* operational.c - bdb backend operational attributes function */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -77,6 +77,7 @@ retry:        /* transaction retry */
 
        opinfo.boi_bdb = be;
        opinfo.boi_txn = ltid;
+       opinfo.boi_locker = TXN_ID ( ltid );
        opinfo.boi_err = 0;
        op->o_private = &opinfo;
 
index 4988e2512238ec18fc82af4e06a25b1fde51f57d..87451ba30734db2b5b7546820e40bd208e8fe1f6 100644 (file)
@@ -1,7 +1,7 @@
 /* passwd.c - bdb backend password routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -41,7 +41,7 @@ bdb_exop_passwd(
        struct berval dn;
        struct berval ndn;
 
-       u_int32_t       locker;
+       u_int32_t       locker = 0;
        DB_LOCK         lock;
 
        assert( reqoid != NULL );
@@ -153,6 +153,7 @@ retry:      /* transaction retry */
 
        opinfo.boi_bdb = be;
        opinfo.boi_txn = ltid;
+       opinfo.boi_locker = locker;
        opinfo.boi_err = 0;
        op->o_private = &opinfo;
 
index d3df97b10abc23f5bd1ba6eeaf428e11b3864481..5ec4228d434f27007586aed40c257c16dfbbaa35 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 2000-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -364,13 +364,19 @@ int bdb_cache_delete_entry(
 );
 void bdb_cache_release_all( Cache *cache );
 
+/*
+ * lcup.c
+ */
+
 #ifdef LDAP_CLIENT_UPDATE
 int bdb_abandon(
        BackendDB       *be,
        Connection      *conn,
        ber_int_t       id
 );
+#endif
 
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
 int bdb_add_psearch_spec(
        BackendDB       *be,
        Connection      *conn,
@@ -384,7 +390,8 @@ int bdb_add_psearch_spec(
        Filter          *filter,
        struct berval   *fstr,
        AttributeName   *attrs,
-       int             attrsonly
+       int             attrsonly,
+       int             protocol
 );
 
 int bdb_psearch(
@@ -395,7 +402,66 @@ int bdb_psearch(
        Entry           *entry,
        int             psearch_type
 );
+#endif
+
+/*
+ * search.c
+ */
 
+#ifdef LDAP_CLIENT_UPDATE
+int
+bdb_build_lcup_update_ctrl(
+       Connection      *conn,
+       Operation       *op,
+       Entry           *e,
+       int             entry_count,
+       LDAPControl     **ctrls,
+       int             num_ctrls,
+       struct berval   *latest_entrycsn_bv,
+       int             isdeleted       );
+
+int
+bdb_build_lcup_done_ctrl(
+       Connection      *conn,
+       Operation       *op,
+       LDAPControl     **ctrls,
+       int             num_ctrls,
+       struct berval   *latest_entrycsn_bv     );
+#endif
+
+#ifdef LDAP_SYNC
+int
+bdb_build_sync_state_ctrl(
+       Connection      *conn,
+       Operation       *op,
+       Entry           *e,
+       int             entry_sync_state,
+       LDAPControl     **ctrls,
+       int             num_ctrls,
+       int             send_cookie,
+       struct berval   *latest_entrycsn_bv     );
+
+int
+bdb_build_sync_done_ctrl(
+       Connection      *conn,
+       Operation       *op,
+       LDAPControl     **ctrls,
+       int             num_ctrls,
+       int             send_cookie,
+       struct berval   *latest_entrycsn_bv     );
+
+int
+bdb_send_ldap_intermediate(
+       Connection  *conn,
+       Operation   *op,
+       ber_int_t   err,
+       const char  *matched,
+       const char  *text,
+       BerVarray   refs,
+       const char  *rspoid,
+       int         state,
+       struct berval *cookie,
+       LDAPControl **ctrls     );
 #endif
 
 #ifdef BDB_REUSE_LOCKERS
diff --git a/servers/slapd/back-bdb/psearch.c b/servers/slapd/back-bdb/psearch.c
new file mode 100644 (file)
index 0000000..a53c0b0
--- /dev/null
@@ -0,0 +1,1080 @@
+/* psearch.c - psearch operations */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include "back-bdb.h"
+#include "idl.h"
+#include "external.h"
+
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+
+#define IS_BDB_REPLACE (( psearch_type == LDAP_PSEARCH_BY_DELETE ) || \
+                      ( psearch_type == LDAP_PSEARCH_BY_SCOPEOUT ))
+#define IS_BDB_LCUP_REPLACE (( protocol == LDAP_CLIENT_UPDATE ) && IS_BDB_REPLACE )
+
+static int psearch_base_candidate(
+       BackendDB       *be,
+       Entry           *e,
+       ID              *ids );
+
+static int psearch_candidates(
+       BackendDB       *be,
+       Operation       *op,
+       Entry           *e,
+       Filter          *filter,
+       int             scope,
+       int             deref,
+       ID              *ids );
+
+int
+bdb_abandon(
+       BackendDB       *be,
+       Connection      *conn,
+       ber_int_t       id )
+{
+       Operation       *ps_list;
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+       LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
+               if ( ps_list->o_connid == conn->c_connid ) {
+                       if ( ps_list->o_msgid == id ) {
+                               ps_list->o_abandon = 1;
+                               LDAP_LIST_REMOVE( ps_list, link );
+                               slap_op_free ( ps_list );
+                               return LDAP_SUCCESS;
+                       }
+               }
+       }
+       return LDAP_UNAVAILABLE;
+}
+
+int
+bdb_cancel(
+       BackendDB       *be,
+       Connection      *conn,
+       ber_int_t       id )
+{
+       Operation       *ps_list;
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+       LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
+               if ( ps_list->o_connid == conn->c_connid ) {
+                       if ( ps_list->o_msgid == id ) {
+                               ps_list->o_cancel = LDAP_CANCEL_DONE;
+                               LDAP_LIST_REMOVE( ps_list, link );
+
+#if 0
+                               bdb_build_sync_done_ctrl( conn, ps_list, ps_list->ctrls, 1, &latest_entrycsn_bv );
+                               send_search_result( conn, ps_list, LDAP_CANCELLED,
+                                               NULL, NULL, NULL, ps_list->ctrls, ps_list->nentries);
+#endif
+                               send_search_result( conn, ps_list, LDAP_CANCELLED,
+                                               NULL, NULL, NULL, NULL, 0);
+
+
+
+                               slap_op_free ( ps_list );
+                               return LDAP_SUCCESS;
+                       }
+               }
+       }
+       return LDAP_UNAVAILABLE;
+}
+
+int
+bdb_add_psearch_spec(
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op,
+       struct berval   *base,
+       struct berval   *nbase,
+       int             scope,
+       int             deref,
+       int             slimit,
+       int             tlimit,
+       Filter          *filter,
+       struct berval   *fstr,
+       AttributeName   *attrs,
+       int             attrsonly,
+       int             protocol        )
+{
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+       LDAP_LIST_FIRST( &op->psearch_spec ) = (struct ldap_psearch_spec *)
+               calloc ( 1, sizeof ( struct ldap_psearch_spec ) );
+
+       LDAP_LIST_FIRST( &op->psearch_spec )->op = op;
+
+       LDAP_LIST_FIRST( &op->psearch_spec )->base = ber_dupbv(NULL, base);
+       LDAP_LIST_FIRST( &op->psearch_spec )->nbase = ber_dupbv(NULL, nbase);
+
+       LDAP_LIST_FIRST( &op->psearch_spec )->scope = scope;
+       LDAP_LIST_FIRST( &op->psearch_spec )->deref = deref;
+       LDAP_LIST_FIRST( &op->psearch_spec )->slimit = slimit;
+       LDAP_LIST_FIRST( &op->psearch_spec )->tlimit = tlimit;
+
+       LDAP_LIST_FIRST( &op->psearch_spec )->filter = filter;
+       LDAP_LIST_FIRST( &op->psearch_spec )->filterstr = ber_dupbv(NULL, fstr);
+       LDAP_LIST_FIRST( &op->psearch_spec )->attrs = attrs;
+
+       LDAP_LIST_FIRST( &op->psearch_spec )->attrsonly = attrsonly;
+
+       LDAP_LIST_FIRST( &op->psearch_spec )->entry_count = 0;
+
+       LDAP_LIST_FIRST( &op->psearch_spec )->protocol = protocol;
+
+       LDAP_LIST_INSERT_HEAD( &bdb->psearch_list, op, link );
+}
+
+int
+bdb_psearch(
+       BackendDB       *be,
+       Connection      *conn,
+       Operation       *op,
+       Operation       *ps_op,
+       Entry           *entry,
+       int             psearch_type    )
+{
+       struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+       int             rc;
+       const char      *text = NULL;
+       time_t          stoptime;
+       unsigned        cursor;
+       ID              id;
+       ID              candidates[BDB_IDL_UM_SIZE];
+       Entry           *e = NULL;
+       BerVarray       v2refs = NULL;
+       Entry           *matched = NULL;
+       struct berval   realbase = { 0, NULL };
+       int             nentries = 0;
+       int             manageDSAit;
+
+       Filter          cookief, csnfnot, csnfeq, csnfand, csnfge;
+       AttributeAssertion      aa_ge, aa_eq;
+       struct berval   entrycsn_bv = { 0, NULL };
+       struct berval   latest_entrycsn_bv = { 0, NULL };
+
+        LDAPControl     *ctrls[SLAP_SEARCH_MAX_CTRLS];
+        int             num_ctrls = 0;
+
+       struct slap_limits_set *limit = NULL;
+       int isroot = 0;
+       int scopeok = 0;
+
+       u_int32_t       locker;
+       DB_LOCK         lock;
+
+       Connection      *ps_conn   = ps_op->o_conn;
+       struct berval   *base      = LDAP_LIST_FIRST( &ps_op->psearch_spec )->base;
+       struct berval   *nbase     = LDAP_LIST_FIRST( &ps_op->psearch_spec )->nbase;
+       int             scope      = LDAP_LIST_FIRST( &ps_op->psearch_spec )->scope;
+       int             deref      = LDAP_LIST_FIRST( &ps_op->psearch_spec )->deref;
+       int             slimit     = LDAP_LIST_FIRST( &ps_op->psearch_spec )->slimit;
+       int             tlimit     = LDAP_LIST_FIRST( &ps_op->psearch_spec )->tlimit;
+       Filter          *filter    = LDAP_LIST_FIRST( &ps_op->psearch_spec )->filter;
+       struct berval   *filterstr = LDAP_LIST_FIRST( &ps_op->psearch_spec )->filterstr;
+       int             attrsonly  = LDAP_LIST_FIRST( &ps_op->psearch_spec )->attrsonly;
+       int             protocol   = LDAP_LIST_FIRST( &ps_op->psearch_spec )->protocol;
+       AttributeName   uuid_attr[2];
+       AttributeName   *attrs;
+
+#ifdef NEW_LOGGING
+       LDAP_LOG ( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, "=> bdb_back_search\n",
+               0, 0, 0);
+#endif
+
+       manageDSAit = get_manageDSAit( ps_op );
+
+       rc = LOCK_ID (bdb->bi_dbenv, &locker );
+       switch(rc) {
+       case 0:
+               break;
+       default:
+               send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
+                       NULL, "internal error", NULL, NULL );
+               return rc;
+       }       
+
+        for ( num_ctrls = 0; num_ctrls < SLAP_SEARCH_MAX_CTRLS; num_ctrls++ )
+                ctrls[num_ctrls] = NULL;
+        num_ctrls = 0;
+
+       if ( !IS_BDB_REPLACE ) {
+               attrs = LDAP_LIST_FIRST(&ps_op->psearch_spec)->attrs;
+       } else {
+#ifdef LDAP_CLIENT_UPDATE
+               if ( protocol == LDAP_CLIENT_UPDATE ) {
+                       attrs = uuid_attr;
+                       attrs[0].an_desc = slap_schema.si_ad_entryUUID;
+                       attrs[0].an_oc = NULL;
+                       ber_dupbv( &attrs[0].an_name, &attrs[0].an_desc->ad_cname );
+                       attrs[1].an_desc = NULL;
+                       attrs[1].an_oc = NULL;
+                       attrs[1].an_name.bv_len = 0;
+                       attrs[1].an_name.bv_val = NULL;
+               } else
+#endif
+#ifdef LDAP_SYNC
+               if (protocol == LDAP_SYNC ) {
+                       attrs = uuid_attr;
+                       attrs[0].an_desc = NULL;
+                       attrs[0].an_oc = NULL;
+                       attrs[0].an_name.bv_len = 0;
+                       attrs[0].an_name.bv_val = NULL;
+               } else
+#endif
+               {
+                       rc = 1;
+                       goto done;
+               }
+       }
+
+       if ( nbase->bv_len == 0 ) {
+               /* DIT root special case */
+               e = (Entry *) &slap_entry_root;
+               rc = 0;
+       } else                                          
+#ifdef BDB_ALIASES
+       /* get entry with reader lock */
+       if ( deref & LDAP_DEREF_FINDING ) {
+               e = deref_dn_r( be, nbase-, &err, &matched, &text );
+
+       } else
+#endif
+       {
+dn2entry_retry:
+               rc = bdb_dn2entry_r( be, NULL, nbase, &e, &matched, 0, locker, &lock );
+       }
+
+       switch(rc) {
+       case DB_NOTFOUND:
+       case 0:
+               break;
+       case LDAP_BUSY:
+               if (e != NULL) {
+                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+                               e, &lock);
+               }
+               if (matched != NULL) {
+                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+                               matched, &lock);
+               }
+               send_ldap_result( ps_conn, ps_op, LDAP_BUSY,
+                       NULL, "ldap server busy", NULL, NULL );
+               LOCK_ID_FREE( bdb->bi_dbenv, locker );
+#ifdef LDAP_CLIENT_UPDATE
+               if ( IS_BDB_LCUP_REPLACE )
+                       ch_free( attrs[0].an_name.bv_val );
+#endif
+               return LDAP_BUSY;
+       case DB_LOCK_DEADLOCK:
+       case DB_LOCK_NOTGRANTED:
+               goto dn2entry_retry;
+       default:
+               if (e != NULL) {
+                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+                               e, &lock);
+               }
+               if (matched != NULL) {
+                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+                               matched, &lock);
+               }
+               send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
+                       NULL, "internal error", NULL, NULL );
+               LOCK_ID_FREE( bdb->bi_dbenv, locker );
+#ifdef LDAP_CLIENT_UPDATE
+               if ( IS_BDB_LCUP_REPLACE )
+                       ch_free( attrs[0].an_name.bv_val );
+#endif
+               return rc;
+       }
+
+       if ( e == NULL ) {
+               struct berval matched_dn = { 0, NULL };
+               BerVarray refs = NULL;
+
+               if ( matched != NULL ) {
+                       BerVarray erefs;
+                       ber_dupbv( &matched_dn, &matched->e_name );
+
+                       erefs = is_entry_referral( matched )
+                               ? get_entry_referrals( be, ps_conn, ps_op, matched )
+                               : NULL;
+
+                       bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+                               matched, &lock);
+                       matched = NULL;
+
+                       if( erefs ) {
+                               refs = referral_rewrite( erefs, &matched_dn,
+                                       base, scope );
+                               ber_bvarray_free( erefs );
+                       }
+
+               } else {
+                       refs = referral_rewrite( default_referral,
+                               NULL, base, scope );
+               }
+
+               send_ldap_result( ps_conn, ps_op,       rc=LDAP_REFERRAL ,
+                       matched_dn.bv_val, text, refs, NULL );
+
+               LOCK_ID_FREE( bdb->bi_dbenv, locker );
+               if ( refs ) ber_bvarray_free( refs );
+               if ( matched_dn.bv_val ) ber_memfree( matched_dn.bv_val );
+#ifdef LDAP_CLIENT_UPDATE
+               if ( IS_BDB_LCUP_REPLACE )
+                       ch_free( attrs[0].an_name.bv_val );
+#endif
+               return rc;
+       }
+
+       if (!manageDSAit && e != &slap_entry_root && is_entry_referral( e ) ) {
+               /* entry is a referral, don't allow add */
+               struct berval matched_dn;
+               BerVarray erefs, refs;
+               
+               ber_dupbv( &matched_dn, &e->e_name );
+               erefs = get_entry_referrals( be, ps_conn, ps_op, e );
+               refs = NULL;
+
+               bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
+               e = NULL;
+
+               if( erefs ) {
+                       refs = referral_rewrite( erefs, &matched_dn,
+                               base, scope );
+                       ber_bvarray_free( erefs );
+               }
+
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, RESULTS, 
+                       "bdb_search: entry is referral\n", 0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "bdb_search: entry is referral\n",
+                       0, 0, 0 );
+#endif
+
+               send_ldap_result( ps_conn, ps_op, LDAP_REFERRAL,
+                       matched_dn.bv_val,
+                       refs ? NULL : "bad referral object",
+                       refs, NULL );
+
+               LOCK_ID_FREE( bdb->bi_dbenv, locker );
+               ber_bvarray_free( refs );
+               ber_memfree( matched_dn.bv_val );
+#ifdef LDAP_CLIENT_UPDATE
+               if ( IS_BDB_LCUP_REPLACE )
+                       ch_free( attrs[0].an_name.bv_val );
+#endif
+               return 1;
+       }
+
+       /* if not root, get appropriate limits */
+       if ( be_isroot( be, &ps_op->o_ndn ) ) {
+               isroot = 1;
+       } else {
+               ( void ) get_limits( be, &ps_op->o_ndn, &limit );
+       }
+
+       /* The time/size limits come first because they require very little
+        * effort, so there's no chance the candidates are selected and then 
+        * the request is not honored only because of time/size constraints */
+
+       /* if no time limit requested, use soft limit (unless root!) */
+       if ( isroot ) {
+               if ( tlimit == 0 ) {
+                       tlimit = -1;    /* allow root to set no limit */
+               }
+
+               if ( slimit == 0 ) {
+                       slimit = -1;
+               }
+
+       } else {
+               /* if no limit is required, use soft limit */
+               if ( tlimit <= 0 ) {
+                       tlimit = limit->lms_t_soft;
+
+               /* if requested limit higher than hard limit, abort */
+               } else if ( tlimit > limit->lms_t_hard ) {
+                       /* no hard limit means use soft instead */
+                       if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) {
+                               tlimit = limit->lms_t_soft;
+
+                       /* positive hard limit means abort */
+                       } else if ( limit->lms_t_hard > 0 ) {
+                               send_search_result( ps_conn, ps_op, 
+                                               LDAP_UNWILLING_TO_PERFORM,
+                                               NULL, NULL, NULL, NULL, 0 );
+                               rc = 0;
+                               goto done;
+                       }
+               
+                       /* negative hard limit means no limit */
+               }
+               
+               /* if no limit is required, use soft limit */
+               if ( slimit <= 0 ) {
+                       slimit = limit->lms_s_soft;
+
+               /* if requested limit higher than hard limit, abort */
+               } else if ( slimit > limit->lms_s_hard ) {
+                       /* no hard limit means use soft instead */
+                       if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) {
+                               slimit = limit->lms_s_soft;
+
+                       /* positive hard limit means abort */
+                       } else if ( limit->lms_s_hard > 0 ) {
+                               send_search_result( ps_conn, ps_op, 
+                                               LDAP_UNWILLING_TO_PERFORM,
+                                               NULL, NULL, NULL, NULL, 0 );
+                               rc = 0; 
+                               goto done;
+                       }
+                       
+                       /* negative hard limit means no limit */
+               }
+       }
+
+       /* compute it anyway; root does not use it */
+       stoptime = ps_op->o_time + tlimit;
+
+       /* select candidates */
+       if ( scope == LDAP_SCOPE_BASE ) {
+               rc = psearch_base_candidate( be, e, candidates );
+       } else {
+               BDB_IDL_ALL( bdb, candidates );
+               rc = psearch_candidates( be, op, e, filter,
+                       scope, deref, candidates );
+       }
+
+       if ( !BDB_IDL_IS_RANGE( candidates ) ) {
+               cursor = bdb_idl_search( candidates, entry->e_id );
+               if ( candidates[cursor] != entry->e_id ) {
+                       goto test_done;
+               }
+       } else {
+               if ( entry->e_id < BDB_IDL_RANGE_FIRST(candidates) &&
+                    entry->e_id > BDB_IDL_RANGE_LAST(candidates) )
+               {
+                       goto test_done;
+               }
+       }
+
+       /* candidates = { e } */
+       candidates[0] = 1;
+       candidates[1] = entry->e_id;
+
+       /* need normalized dn below */
+       ber_dupbv( &realbase, &e->e_nname );
+
+       if ( e != &slap_entry_root ) {
+               bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+       }
+       e = NULL;
+
+       if ( candidates[0] == 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS,
+                       "bdb_search: no candidates\n", 0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "bdb_search: no candidates\n",
+                       0, 0, 0 );
+#endif
+
+               send_search_result( ps_conn, ps_op,
+                       LDAP_SUCCESS,
+                       NULL, NULL, NULL, NULL, 0 );
+
+               rc = 1;
+               goto done;
+       }
+
+       /* if not root and candidates exceed to-be-checked entries, abort */
+       if ( !isroot && limit->lms_s_unchecked != -1 ) {
+               if ( BDB_IDL_N(candidates) > (unsigned) limit->lms_s_unchecked ) {
+                       send_search_result( ps_conn, ps_op, LDAP_ADMINLIMIT_EXCEEDED,
+                               NULL, NULL, NULL, NULL, 0 );
+                       rc = 1;
+                       goto done;
+               }
+       }
+
+#ifdef LDAP_CLIENT_UPDATE
+       if ( protocol == LDAP_CLIENT_UPDATE ) {
+               cookief.f_choice = LDAP_FILTER_AND;
+               cookief.f_and = &csnfnot;
+               cookief.f_next = NULL;
+       
+               csnfnot.f_choice = LDAP_FILTER_NOT;
+               csnfnot.f_not = &csnfeq;
+               csnfnot.f_next = &csnfand;
+
+               csnfeq.f_choice = LDAP_FILTER_EQUALITY;
+               csnfeq.f_ava = &aa_eq;
+               csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
+               ber_dupbv( &csnfeq.f_av_value, &ps_op->o_clientupdate_state );
+
+               csnfand.f_choice = LDAP_FILTER_AND;
+               csnfand.f_and = &csnfge;
+               csnfand.f_next = NULL;
+       
+               csnfge.f_choice = LDAP_FILTER_GE;
+               csnfge.f_ava = &aa_ge;
+               csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
+               ber_dupbv( &csnfge.f_av_value, &ps_op->o_clientupdate_state );
+               csnfge.f_next = filter;
+       }
+#endif
+#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
+       else
+#endif
+#ifdef LDAP_SYNC
+       if ( protocol == LDAP_SYNC ) {
+               cookief.f_choice = LDAP_FILTER_AND;
+               cookief.f_and = &csnfnot;
+               cookief.f_next = NULL;
+       
+               csnfnot.f_choice = LDAP_FILTER_NOT;
+               csnfnot.f_not = &csnfeq;
+               csnfnot.f_next = &csnfand;
+
+               csnfeq.f_choice = LDAP_FILTER_EQUALITY;
+               csnfeq.f_ava = &aa_eq;
+               csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
+               ber_dupbv( &csnfeq.f_av_value, &ps_op->o_sync_state );
+
+               csnfand.f_choice = LDAP_FILTER_AND;
+               csnfand.f_and = &csnfge;
+               csnfand.f_next = NULL;
+       
+               csnfge.f_choice = LDAP_FILTER_GE;
+               csnfge.f_ava = &aa_ge;
+               csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
+               ber_dupbv( &csnfge.f_av_value, &ps_op->o_sync_state );
+               csnfge.f_next = filter;
+       }
+#endif
+
+       id = entry->e_id;
+
+       /* check for abandon */
+       if ( ps_op->o_abandon ) {
+               rc = 0;
+               goto done;
+       }
+
+       /* check time limit */
+       if ( tlimit != -1 && slap_get_time() > stoptime ) {
+               send_search_result( ps_conn, ps_op, rc = LDAP_TIMELIMIT_EXCEEDED,
+                       NULL, NULL, v2refs, NULL, nentries );
+               goto done;
+       }
+
+       e = entry;
+
+#ifdef BDB_SUBENTRIES
+       if ( is_entry_subentry( e ) ) {
+               if( scope != LDAP_SCOPE_BASE ) {
+                       if(!get_subentries_visibility( ps_op )) {
+                               /* only subentries are visible */
+                               goto test_done;
+                       }
+
+               } else if ( get_subentries( ps_op ) &&
+                       !get_subentries_visibility( ps_op ))
+               {
+                       /* only subentries are visible */
+                       goto test_done;
+               }
+
+       } else if ( get_subentries_visibility( ps_op )) {
+               /* only subentries are visible */
+               goto test_done;
+       }
+#endif
+
+#ifdef BDB_ALIASES
+       if ( deref & LDAP_DEREF_SEARCHING && is_entry_alias( e ) ) {
+               Entry *matched;
+               int err;
+               const char *text;
+               
+               e = deref_entry_r( be, e, &err, &matched, &text );
+
+               if( e == NULL ) {
+                       e = matched;
+                       goto test_done;
+               }
+
+               if( e->e_id == id ) {
+                       /* circular loop */
+                       goto test_done;
+               }
+
+               /* need to skip alias which deref into scope */
+               if( scope & LDAP_SCOPE_ONELEVEL ) {
+                       struct berval   pdn;
+                       
+                       dnParent( &e->e_nname, &pdn ):
+                       if ( ber_bvcmp( pdn, &realbase ) ) {
+                               goto test_done;
+                       }
+
+               } else if ( dnIsSuffix( &e->e_nname, &realbase ) ) {
+                       /* alias is within scope */
+#ifdef NEW_LOGGING
+                       LDAP_LOG ( OPERATION, RESULTS,
+                               "bdb_search: \"%s\" in subtree\n", e->edn, 0, 0);
+#else
+                       Debug( LDAP_DEBUG_TRACE,
+                               "bdb_search: \"%s\" in subtree\n",
+                               e->e_dn, 0, 0 );
+#endif
+                       goto test_done;
+               }
+
+               scopeok = 1;
+       }
+#endif
+
+       /*
+        * if it's a referral, add it to the list of referrals. only do
+        * this for non-base searches, and don't check the filter
+        * explicitly here since it's only a candidate anyway.
+        */
+       if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
+               is_entry_referral( e ) )
+       {
+               struct berval   dn;
+
+               /* check scope */
+               if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
+                       if ( !be_issuffix( be, &e->e_nname ) ) {
+                               dnParent( &e->e_nname, &dn );
+                               scopeok = dn_match( &dn, &realbase );
+                       } else {
+                               scopeok = (realbase.bv_len == 0);
+                       }
+
+               } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
+                       scopeok = dnIsSuffix( &e->e_nname, &realbase );
+
+               } else {
+                       scopeok = 1;
+               }
+
+               if( scopeok ) {
+                       BerVarray erefs = get_entry_referrals(
+                               be, ps_conn, ps_op, e );
+                       BerVarray refs = referral_rewrite( erefs,
+                               &e->e_name, NULL,
+                               scope == LDAP_SCOPE_SUBTREE
+                                       ? LDAP_SCOPE_SUBTREE
+                                       : LDAP_SCOPE_BASE );
+
+                       send_search_reference( be, ps_conn, ps_op,
+                               e, refs, NULL, &v2refs );
+
+                       ber_bvarray_free( refs );
+
+               } else {
+#ifdef NEW_LOGGING
+                       LDAP_LOG(OPERATION, DETAIL2, 
+                               "bdb_search: candidate referral %ld scope not okay\n",
+                               id, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_TRACE,
+                               "bdb_search: candidate referral %ld scope not okay\n",
+                               id, 0, 0 );
+#endif
+               }
+
+               goto test_done;
+       }
+
+       if ( psearch_type != LDAP_PSEARCH_BY_SCOPEOUT ) {
+               rc = test_filter( be, ps_conn, ps_op, e, &cookief );
+       } else {
+               rc = LDAP_COMPARE_TRUE;
+       }
+
+       if ( rc == LDAP_COMPARE_TRUE ) {
+               struct berval   dn;
+
+               /* check scope */
+               if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
+                       if ( be_issuffix( be, &e->e_nname ) ) {
+                               scopeok = (realbase.bv_len == 0);
+                       } else {
+                               dnParent( &e->e_nname, &dn );
+                               scopeok = dn_match( &dn, &realbase );
+                       }
+
+               } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
+                       scopeok = dnIsSuffix( &e->e_nname, &realbase );
+
+               } else {
+                       scopeok = 1;
+               }
+
+               if ( scopeok ) {
+                       /* check size limit */
+                       if ( --slimit == -1 ) {
+                               send_search_result( ps_conn, ps_op,
+                                       rc = LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
+                                       v2refs, NULL, nentries );
+                               goto done;
+                       }
+
+                       if (e) {
+                               int result;
+                               
+#if 0  /* noop is masked SLAP_CTRL_UPDATE */
+                               if( ps_op->o_noop ) {
+                                       result = 0;
+                               } else
+#endif
+                               {
+#ifdef LDAP_SYNC
+                                               int premodify_found = 0;
+                                               int entry_sync_state;
+#endif
+
+                                       if ( psearch_type == LDAP_PSEARCH_BY_ADD ||
+                                            psearch_type == LDAP_PSEARCH_BY_DELETE ||
+                                            psearch_type == LDAP_PSEARCH_BY_MODIFY ||
+                                            psearch_type == LDAP_PSEARCH_BY_SCOPEOUT )
+                                       {
+                                               if ( psearch_type == LDAP_PSEARCH_BY_MODIFY ) {
+                                                       struct psid_entry* psid_e;
+                                                       LDAP_LIST_FOREACH( psid_e, &op->premodify_list, link)
+                                                       {
+                                                               if( psid_e->ps == LDAP_LIST_FIRST(&ps_op->psearch_spec))
+                                                               {
+#ifdef LDAP_SYNC
+                                                                       premodify_found = 1;
+#endif
+                                                                       LDAP_LIST_REMOVE(psid_e, link);
+                                                                       break;
+                                                               }
+                                                       }
+                                                       if (psid_e != NULL) free (psid_e);
+                                               }
+#ifdef LDAP_SYNC
+                                               if ( psearch_type == LDAP_PSEARCH_BY_ADD )
+                                                       entry_sync_state = LDAP_SYNC_ADD;
+                                               else if ( psearch_type == LDAP_PSEARCH_BY_DELETE )
+                                                       entry_sync_state = LDAP_SYNC_DELETE;
+                                               else if ( psearch_type == LDAP_PSEARCH_BY_MODIFY ) {
+                                                       if ( premodify_found )
+                                                               entry_sync_state = LDAP_SYNC_MODIFY;
+                                                       else
+                                                               entry_sync_state = LDAP_SYNC_ADD;
+                                               } else if ( psearch_type == LDAP_PSEARCH_BY_SCOPEOUT )
+                                                       entry_sync_state = LDAP_SYNC_DELETE;
+                                               else {
+                                                       rc = 1;
+                                                       goto done;
+                                               }
+#endif
+
+#ifdef LDAP_CLIENT_UPDATE
+                                               if ( protocol == LDAP_CLIENT_UPDATE ) {
+                                                       int entry_count = ++(LDAP_LIST_FIRST(&ps_op->psearch_spec)->entry_count);
+                                                       if ( IS_BDB_REPLACE ) {
+                                                               rc = bdb_build_lcup_update_ctrl( ps_conn, ps_op, e, entry_count, ctrls,
+                                                                               num_ctrls++, &latest_entrycsn_bv, SLAP_LCUP_ENTRY_DELETED_TRUE );
+                                                       } else {
+                                                               rc = bdb_build_lcup_update_ctrl( ps_conn, ps_op, e, entry_count, ctrls,
+                                                                               num_ctrls++, &latest_entrycsn_bv, SLAP_LCUP_ENTRY_DELETED_FALSE );
+                                                       }
+                                                       if ( rc != LDAP_SUCCESS )
+                                                               goto done;
+                                                       result = send_search_entry( be, ps_conn, ps_op, e, attrs, attrsonly, ctrls );
+                                                       if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+                                                               ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+                                                       ch_free( ctrls[--num_ctrls] );
+                                                       ctrls[num_ctrls] = NULL;
+                                               } else
+#endif
+#ifdef LDAP_SYNC
+                                               if ( protocol == LDAP_SYNC ) {
+                                                       rc = bdb_build_sync_state_ctrl( ps_conn, ps_op, e, entry_sync_state, ctrls,
+                                                                                       num_ctrls++, 1, &latest_entrycsn_bv );
+                                                       if ( rc != LDAP_SUCCESS )
+                                                               goto done;
+                                                       result = send_search_entry( be, ps_conn, ps_op, e, attrs, attrsonly, ctrls );
+                                                       if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+                                                               ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+                                                       ch_free( ctrls[--num_ctrls] );
+                                                       ctrls[num_ctrls] = NULL;
+                                               } else
+#endif
+                                               {
+                                                       rc = 1;
+                                                       goto done;
+                                               }
+
+                                       } else if ( psearch_type == LDAP_PSEARCH_BY_PREMODIFY ) {
+                                               struct psid_entry* psid_e;
+                                               psid_e = (struct psid_entry *) calloc (1,
+                                                       sizeof(struct psid_entry));
+                                               psid_e->ps = LDAP_LIST_FIRST(&ps_op->psearch_spec);
+                                               LDAP_LIST_INSERT_HEAD( &op->premodify_list,
+                                                       psid_e, link );
+
+                                       } else {
+                                               printf("Error !\n");
+                                       }
+                               }
+
+                               switch (result) {
+                               case 0:         /* entry sent ok */
+                                       nentries++;
+                                       break;
+                               case 1:         /* entry not sent */
+                                       break;
+                               case -1:        /* connection closed */
+                                       rc = LDAP_OTHER;
+                                       goto done;
+                               }
+                       }
+               } else {
+#ifdef NEW_LOGGING
+                       LDAP_LOG ( OPERATION, RESULTS,
+                               "bdb_search: %ld scope not okay\n", (long) id, 0, 0);
+#else
+                       Debug( LDAP_DEBUG_TRACE,
+                               "bdb_search: %ld scope not okay\n", (long) id, 0, 0 );
+#endif
+               }
+       } else {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS,
+                       "bdb_search: %ld does match filter\n", (long) id, 0, 0);
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "bdb_search: %ld does match filter\n",
+                       (long) id, 0, 0 );
+#endif
+       }
+
+test_done:
+       rc = LDAP_SUCCESS;
+
+done:
+       if ( csnfeq.f_ava != NULL && csnfeq.f_av_value.bv_val != NULL ) {
+               ch_free( csnfeq.f_av_value.bv_val );
+       }
+
+       if ( csnfge.f_ava != NULL && csnfge.f_av_value.bv_val != NULL ) {
+               ch_free( csnfge.f_av_value.bv_val );
+       }
+
+       LOCK_ID_FREE( bdb->bi_dbenv, locker );
+
+       if( v2refs ) ber_bvarray_free( v2refs );
+       if( realbase.bv_val ) ch_free( realbase.bv_val );
+#ifdef LDAP_CLIENT_UPDATE
+       if ( IS_BDB_LCUP_REPLACE )
+               ch_free( attrs[0].an_name.bv_val );
+#endif
+
+       return rc;
+}
+
+static int psearch_base_candidate(
+       BackendDB       *be,
+       Entry   *e,
+       ID              *ids )
+{
+#ifdef NEW_LOGGING
+       LDAP_LOG ( OPERATION, ENTRY,
+               "psearch_base_candidate: base: \"%s\" (0x%08lx)\n", e->e_dn, (long) e->e_id, 0);
+#else
+       Debug(LDAP_DEBUG_ARGS, "psearch_base_candidates: base: \"%s\" (0x%08lx)\n",
+               e->e_dn, (long) e->e_id, 0);
+#endif
+
+       ids[0] = 1;
+       ids[1] = e->e_id;
+       return 0;
+}
+
+/* Look for "objectClass Present" in this filter.
+ * Also count depth of filter tree while we're at it.
+ */
+static int psearch_oc_filter(
+       Filter *f,
+       int cur,
+       int *max
+)
+{
+       int rc = 0;
+
+       if( cur > *max ) *max = cur;
+
+       switch(f->f_choice) {
+       case LDAP_FILTER_PRESENT:
+               if (f->f_desc == slap_schema.si_ad_objectClass) {
+                       rc = 1;
+               }
+               break;
+
+       case LDAP_FILTER_AND:
+       case LDAP_FILTER_OR:
+               cur++;
+               for (f=f->f_and; f; f=f->f_next) {
+                       (void) psearch_oc_filter(f, cur, max);
+               }
+               break;
+
+       default:
+               break;
+       }
+       return rc;
+}
+
+static int psearch_candidates(
+       BackendDB *be,
+       Operation *op,
+       Entry *e,
+       Filter *filter,
+       int scope,
+       int deref,
+       ID      *ids )
+{
+       int rc, depth = 1;
+       Filter          f, scopef, rf, xf;
+       ID              *stack;
+       AttributeAssertion aa_ref;
+#ifdef BDB_SUBENTRIES
+       Filter  sf;
+       AttributeAssertion aa_subentry;
+#endif
+#ifdef BDB_ALIASES
+       Filter  af;
+       AttributeAssertion aa_alias;
+#endif
+
+       /*
+        * This routine takes as input a filter (user-filter)
+        * and rewrites it as follows:
+        *      (&(scope=DN)[(objectClass=subentry)]
+        *              (|[(objectClass=referral)(objectClass=alias)](user-filter))
+        */
+
+#ifdef NEW_LOGGING
+       LDAP_LOG ( OPERATION, ENTRY,
+               "psearch_candidates: base=\"%s\" (0x%08lx) scope=%d\n", 
+               e->e_dn, (long) e->e_id, scope);
+#else
+       Debug(LDAP_DEBUG_TRACE,
+               "psearch_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
+               e->e_dn, (long) e->e_id, scope );
+#endif
+
+       xf.f_or = filter;
+       xf.f_choice = LDAP_FILTER_OR;
+       xf.f_next = NULL;
+
+       /* If the user's filter uses objectClass=*,
+        * these clauses are redundant.
+        */
+       if (!psearch_oc_filter(filter, 1, &depth) && !get_subentries_visibility(op) ) {
+               if( !get_manageDSAit(op) ) { /* match referrals */
+                       struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" };
+                       rf.f_choice = LDAP_FILTER_EQUALITY;
+                       rf.f_ava = &aa_ref;
+                       rf.f_av_desc = slap_schema.si_ad_objectClass;
+                       rf.f_av_value = bv_ref;
+                       rf.f_next = xf.f_or;
+                       xf.f_or = &rf;
+               }
+
+#ifdef BDB_ALIASES
+               if( deref & LDAP_DEREF_SEARCHING ) { /* match aliases */
+                       struct berval bv_alias = { sizeof("ALIAS")-1, "ALIAS" };
+                       af.f_choice = LDAP_FILTER_EQUALITY;
+                       af.f_ava = &aa_alias;
+                       af.f_av_desc = slap_schema.si_ad_objectClass;
+                       af.f_av_value = bv_alias;
+                       af.f_next = xf.f_or;
+                       xf.f_or = &af;
+               }
+#endif
+               /* We added one of these clauses, filter depth increased */
+               if( xf.f_or != filter ) depth++;
+       }
+
+       f.f_next = NULL;
+       f.f_choice = LDAP_FILTER_AND;
+       f.f_and = &scopef;
+       scopef.f_choice = scope == LDAP_SCOPE_SUBTREE
+               ? SLAPD_FILTER_DN_SUBTREE
+               : SLAPD_FILTER_DN_ONE;
+       scopef.f_dn = &e->e_nname;
+       scopef.f_next = xf.f_or == filter ? filter : &xf ;
+       /* Filter depth increased again, adding scope clause */
+       depth++;
+
+#ifdef BDB_SUBENTRIES
+       if( get_subentries_visibility( op ) ) {
+               struct berval bv_subentry = { sizeof("SUBENTRY")-1, "SUBENTRY" };
+               sf.f_choice = LDAP_FILTER_EQUALITY;
+               sf.f_ava = &aa_subentry;
+               sf.f_av_desc = slap_schema.si_ad_objectClass;
+               sf.f_av_value = bv_subentry;
+               sf.f_next = scopef.f_next;
+               scopef.f_next = &sf;
+       }
+#endif
+
+       /* Allocate IDL stack, plus 1 more for former tmp */
+       stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
+
+       rc = bdb_filter_candidates( be, &f, ids, stack, stack+BDB_IDL_UM_SIZE );
+
+       ch_free( stack );
+
+       if( rc ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, DETAIL1,
+                       "bdb_psearch_candidates: failed (rc=%d)\n", rc, 0, 0  );
+#else
+               Debug(LDAP_DEBUG_TRACE,
+                       "bdb_psearch_candidates: failed (rc=%d)\n",
+                       rc, NULL, NULL );
+#endif
+
+       } else {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, DETAIL1,
+                       "bdb_psearch_candidates: id=%ld first=%ld last=%ld\n",
+                       (long) ids[0], (long) BDB_IDL_FIRST(ids), 
+                       (long) BDB_IDL_LAST(ids));
+#else
+               Debug(LDAP_DEBUG_TRACE,
+                       "bdb_psearch_candidates: id=%ld first=%ld last=%ld\n",
+                       (long) ids[0],
+                       (long) BDB_IDL_FIRST(ids),
+                       (long) BDB_IDL_LAST(ids) );
+#endif
+       }
+
+       return rc;
+}
+
+
+#endif
index 40abe31cd7494835fe293d2b1ea5c257a42b00de..7f83a341fe656f4c053eecff0b0dc5771398003b 100644 (file)
@@ -1,7 +1,7 @@
 /* search.c - search operation */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -26,6 +26,12 @@ static int search_candidates(
        int scope,
        int deref,
        ID      *ids );
+static void send_pagerequest_response( 
+       Connection      *conn,
+       Operation *op,
+       ID  lastid,
+       int nentries,
+       int tentries );                 
 
 int
 bdb_search(
@@ -55,20 +61,30 @@ bdb_search(
        struct berval   realbase = { 0, NULL };
        int             nentries = 0;
        int             manageDSAit;
+       int             tentries = 0;
+       ID              lastid = NOID;
 
-#ifdef LDAP_CLIENT_UPDATE
-       Filter lcupf, csnfnot, csnfeq, csnfand, csnfge;
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+       Filter          cookief, csnfnot, csnfeq, csnfand, csnfge;
        AttributeAssertion aa_ge, aa_eq;
        int             entry_count = 0;
-       struct berval entrycsn_bv = { 0, NULL };
-       struct berval latest_entrycsn_bv = { 0, NULL };
-#endif /* LDAP_CLIENT_UPDATE */
+       struct berval   latest_entrycsn_bv = { 0, NULL };
+       LDAPControl     *ctrls[SLAP_SEARCH_MAX_CTRLS];
+       int             num_ctrls = 0;
+#endif
+
+#ifdef LDAP_SYNC
+       int             rc_sync = 0;
+       int             entry_sync_state;
+       AttributeName   null_attr;
+#endif
 
        struct slap_limits_set *limit = NULL;
        int isroot = 0;
 
-       u_int32_t       locker;
+       u_int32_t       locker = 0;
        DB_LOCK         lock;
+       struct bdb_op_info opinfo;
 
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 );
@@ -79,16 +95,38 @@ bdb_search(
 
 #ifdef LDAP_CLIENT_UPDATE
        if ( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) {
-               bdb_add_psearch_spec( be, conn, op, base, base, scope,
-                       deref, slimit, tlimit, filter, filterstr, attrs, attrsonly );
+               bdb_add_psearch_spec( be, conn, op, base, base, scope, deref, slimit,
+                               tlimit, filter, filterstr, attrs, attrsonly, LDAP_CLIENT_UPDATE );
                return LDAP_SUCCESS;
        }
 #endif
+#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
+       else
+#endif
+#ifdef LDAP_SYNC
+       /* psearch needs to be registered before refresh begins */
+       /* psearch and refresh transmission is serialized in send_ldap_ber() */
+       if ( op->o_sync_mode & SLAP_SYNC_PERSIST ) {
+               bdb_add_psearch_spec( be, conn, op, base, base, scope, deref, slimit,
+                               tlimit, filter, filterstr, attrs, attrsonly, LDAP_SYNC );
+       }
+       null_attr.an_desc = NULL;
+       null_attr.an_oc = NULL;
+       null_attr.an_name.bv_len = 0;
+       null_attr.an_name.bv_val = NULL;
+#endif
+
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+       for ( num_ctrls = 0; num_ctrls < SLAP_SEARCH_MAX_CTRLS; num_ctrls++ )
+               ctrls[num_ctrls] = NULL;
+       num_ctrls = 0;
+#endif
 
 
        manageDSAit = get_manageDSAit( op );
 
        rc = LOCK_ID (bdb->bi_dbenv, &locker );
+
        switch(rc) {
        case 0:
                break;
@@ -98,6 +136,12 @@ bdb_search(
                return rc;
        }
 
+       opinfo.boi_bdb = be;
+       opinfo.boi_txn = NULL;
+       opinfo.boi_locker = locker;
+       opinfo.boi_err = 0;
+       op->o_private = &opinfo;
+
        if ( nbase->bv_len == 0 ) {
                /* DIT root special case */
                e = (Entry *) &slap_entry_root;
@@ -266,7 +310,11 @@ dn2entry_retry:
                
                /* if no limit is required, use soft limit */
                if ( slimit <= 0 ) {
-                       slimit = limit->lms_s_soft;
+                       if ( get_pagedresults(op) && limit->lms_s_pr != 0 ) {
+                               slimit = limit->lms_s_pr;
+                       } else {
+                               slimit = limit->lms_s_soft;
+                       }
 
                /* if requested limit higher than hard limit, abort */
                } else if ( slimit > limit->lms_s_hard ) {
@@ -342,11 +390,49 @@ dn2entry_retry:
                }
        }
 
+       if ( isroot || !limit->lms_s_pr_hide ) {
+               tentries = BDB_IDL_N(candidates);
+       }
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+       if ( get_pagedresults(op) ) {
+               if ( op->o_pagedresults_state.ps_cookie == 0 ) {
+                       id = 0;
+               } else {
+                       if ( op->o_pagedresults_size == 0 ) {
+                               send_search_result( conn, op, LDAP_SUCCESS,
+                                       NULL, "search abandoned by pagedResult size=0",
+                                       NULL, NULL, 0);
+                               goto done;
+                       }
+                       for ( id = bdb_idl_first( candidates, &cursor );
+                               id != NOID && id <= (ID)( op->o_pagedresults_state.ps_cookie );
+                               id = bdb_idl_next( candidates, &cursor ) );
+               }
+               if ( cursor == NOID ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG ( OPERATION, RESULTS, 
+                               "bdb_search: no paged results candidates\n", 
+                       0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_TRACE, 
+                               "bdb_search: no paged results candidates\n",
+                               0, 0, 0 );
+#endif
+                       send_pagerequest_response( conn, op, lastid, 0, 0 );
+
+                       rc = 1;
+                       goto done;
+               }
+               goto loop_begin;
+       }
+#endif
+
 #ifdef LDAP_CLIENT_UPDATE
        if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
-               lcupf.f_choice = LDAP_FILTER_AND;
-               lcupf.f_and = &csnfnot;
-               lcupf.f_next = NULL;
+               cookief.f_choice = LDAP_FILTER_AND;
+               cookief.f_and = &csnfnot;
+               cookief.f_next = NULL;
 
                csnfnot.f_choice = LDAP_FILTER_NOT;
                csnfnot.f_not = &csnfeq;
@@ -367,20 +453,62 @@ dn2entry_retry:
                ber_dupbv( &csnfge.f_av_value, &op->o_clientupdate_state );
                csnfge.f_next = filter;
        }
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
+       else
+#endif
+#ifdef LDAP_SYNC
+       if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+               cookief.f_choice = LDAP_FILTER_AND;
+               cookief.f_and = &csnfnot;
+               cookief.f_next = NULL;
+
+               csnfnot.f_choice = LDAP_FILTER_NOT;
+               csnfnot.f_not = &csnfeq;
+               csnfnot.f_next = &csnfand;
+
+               csnfeq.f_choice = LDAP_FILTER_EQUALITY;
+               csnfeq.f_ava = &aa_eq;
+               csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
+               ber_dupbv( &csnfeq.f_av_value, &op->o_sync_state );
+
+               csnfand.f_choice = LDAP_FILTER_AND;
+               csnfand.f_and = &csnfge;
+               csnfand.f_next = NULL;
+
+               csnfge.f_choice = LDAP_FILTER_GE;
+               csnfge.f_ava = &aa_ge;
+               csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
+               ber_dupbv( &csnfge.f_av_value, &op->o_sync_state );
+               csnfge.f_next = filter;
+       }
+#endif
 
        for ( id = bdb_idl_first( candidates, &cursor );
                id != NOID;
                id = bdb_idl_next( candidates, &cursor ) )
        {
+
                int             scopeok = 0;
 
+loop_begin:
                /* check for abandon */
                if ( op->o_abandon ) {
                        rc = 0;
                        goto done;
                }
 
+#ifdef LDAP_EXOP_X_CANCEL
+               if ( op->o_cancel ) {
+                       assert( op->o_cancel == LDAP_CANCEL_REQ );
+                       rc = 0;
+                       send_search_result( conn, op, LDAP_CANCELLED,
+                                       NULL, NULL, NULL, NULL, 0 );
+                       op->o_cancel = LDAP_CANCEL_ACK;
+                       goto done;
+               }
+#endif
+
                /* check time limit */
                if ( tlimit != -1 && slap_get_time() > stoptime ) {
                        send_search_result( conn, op, rc = LDAP_TIMELIMIT_EXCEEDED,
@@ -540,9 +668,22 @@ id2entry_retry:
                /* if it matches the filter and scope, send it */
 #ifdef LDAP_CLIENT_UPDATE
                if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
-                       rc = test_filter( be, conn, op, e, &lcupf );
+                       rc = test_filter( be, conn, op, e, &cookief );
                } else
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#ifdef LDAP_SYNC
+               if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+                       rc_sync = test_filter( be, conn, op, e, &cookief );
+                       rc      = test_filter( be, conn, op, e, filter );
+                       if ( rc == LDAP_COMPARE_TRUE ) {
+                               if ( rc_sync == LDAP_COMPARE_TRUE ) {
+                                       entry_sync_state = LDAP_SYNC_ADD;
+                               } else {
+                                       entry_sync_state = LDAP_SYNC_PRESENT;
+                               }
+                       }
+               } else
+#endif
                {
                        rc = test_filter( be, conn, op, e, filter );
                }
@@ -578,6 +719,17 @@ id2entry_retry:
                                        goto done;
                                }
 
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+                               if ( get_pagedresults(op) ) {
+                                       if ( nentries >= op->o_pagedresults_size ) {
+                                               send_pagerequest_response( conn, op,
+                                                       lastid, nentries, tentries );
+                                               goto done;
+                                       }
+                                       lastid = id;
+                               }
+#endif
+
                                if (e) {
                                        int result;
                                        
@@ -589,118 +741,41 @@ id2entry_retry:
                                        {
 #ifdef LDAP_CLIENT_UPDATE
                                                if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
-                                                       Attribute* a;
-                                                       int ret;
-                                                       int res;
-                                                       const char *text = NULL;
-                                                       LDAPControl *ctrls[2];
-                                                       struct berval *bv;
-
-                                                       BerElement *ber = ber_alloc_t( LBER_USE_DER );
+                                                       rc = bdb_build_lcup_update_ctrl( conn, op, e, ++entry_count, ctrls,
+                                                                       num_ctrls++, &latest_entrycsn_bv, SLAP_LCUP_ENTRY_DELETED_FALSE );
+                                                       if ( rc != LDAP_SUCCESS )
+                                                               goto done;
+                                                       result = send_search_entry( be, conn, op,
+                                                                       e, attrs, attrsonly, ctrls);
 
-                                                       if ( ber == NULL ) {
-#ifdef NEW_LOGGING
-                                                               LDAP_LOG ( OPERATION, RESULTS, 
-                                                                       "bdb_search: ber_alloc_t failed\n",
-                                                                       0, 0, 0 );
-#else
-                                                               Debug( LDAP_DEBUG_TRACE,
-                                                                       "bdb_search: ber_alloc_t failed\n",
-                                                                       0, 0, 0 );
+                                                       if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+                                                               ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+                                                       ch_free( ctrls[--num_ctrls] );
+                                                       ctrls[num_ctrls] = NULL;
+                                               } else
 #endif
-                                                               send_ldap_result( conn, op, rc=LDAP_OTHER,
-                                                                       NULL, "internal error", NULL, NULL );
+#ifdef LDAP_SYNC
+                                               if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+                                                       rc = bdb_build_sync_state_ctrl( conn, op, e, entry_sync_state, ctrls,
+                                                                       num_ctrls++, 0, &latest_entrycsn_bv );
+                                                       if ( rc != LDAP_SUCCESS )
                                                                goto done;
-                                                       }
 
-                                                       entry_count++;
-
-                                                       ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) );
-                                                       ctrls[1] = NULL;
-
-                                                       if ( entry_count % op->o_clientupdate_interval == 0 ) {
-                                                               /* Send cookie */
-                                                               for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
-                                                                       AttributeDescription *desc = a->a_desc;
-                                                                       if ( desc == slap_schema.si_ad_entryCSN ) {
-                                                                               ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
-                                                                               if ( latest_entrycsn_bv.bv_val == NULL ) {
-                                                                                       ber_dupbv( &latest_entrycsn_bv, &entrycsn_bv );
-                                                                               } else {
-                                                                                       res = value_match( &ret, desc,
-                                                                                               desc->ad_type->sat_ordering,
-                                                                                               SLAP_MR_ASSERTION_SYNTAX_MATCH,
-                                                                                               &entrycsn_bv, &latest_entrycsn_bv, &text );
-                                                                                       if ( res != LDAP_SUCCESS ) {
-                                                                                               ret = 0;
-#ifdef NEW_LOGGING
-                                                                                               LDAP_LOG ( OPERATION, RESULTS, 
-                                                                                                       "bdb_search: value_match failed\n",
-                                                                                                       0, 0, 0 );
-#else
-                                                                                               Debug( LDAP_DEBUG_TRACE,
-                                                                                                       "bdb_search: value_match failed\n",
-                                                                                                       0, 0, 0 );
-#endif
-                                                                                       }
-
-                                                                                       if ( ret > 0 ) {
-                                                                                               ch_free( latest_entrycsn_bv.bv_val );
-                                                                                               latest_entrycsn_bv.bv_val = NULL;
-                                                                                               ber_dupbv( &latest_entrycsn_bv,
-                                                                                                       &entrycsn_bv );
-                                                                                       }
-                                                                               }
-                                                                       }
-                                                               }
-
-                                                               ber_printf( ber,
-                                                                       "{bb{sON}N}",
-                                                                       SLAP_LCUP_STATE_UPDATE_FALSE,
-                                                                       SLAP_LCUP_ENTRY_DELETED_FALSE,
-                                                                       LCUP_COOKIE_OID, &entrycsn_bv );
-
-                                                               ch_free( entrycsn_bv.bv_val );
-                                                               entrycsn_bv.bv_val = NULL;
-
-                                                       } else {
-                                                               /* Do not send cookie */
-                                                               ber_printf( ber,
-                                                                       "{bbN}",
-                                                                       SLAP_LCUP_STATE_UPDATE_FALSE,
-                                                                       SLAP_LCUP_ENTRY_DELETED_FALSE );
+                                                       if ( rc_sync == LDAP_COMPARE_TRUE ) { /* ADD */
+                                                               result = send_search_entry( be, conn, op,
+                                                                               e, attrs, attrsonly, ctrls);
+                                                       } else { /* PRESENT */
+                                                               result = send_search_entry( be, conn, op,
+                                                                               e, &null_attr, attrsonly, ctrls);
                                                        }
 
-                                                       ctrls[0]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE;
-                                                       ctrls[0]->ldctl_iscritical = op->o_clientupdate;
-                                                       ret = ber_flatten( ber, &bv );
-
-                                                       if ( ret < 0 ) {
-#ifdef NEW_LOGGING
-                                                               LDAP_LOG ( OPERATION, RESULTS, 
-                                                                       "bdb_search: ber_flatten failed\n",
-                                                                       0, 0, 0 );
-#else
-                                                               Debug( LDAP_DEBUG_TRACE,
-                                                                       "bdb_search: ber_flatten failed\n",
-                                                                       0, 0, 0 );
+                                                       if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+                                                               ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+                                                       ch_free( ctrls[--num_ctrls] );
+                                                       ctrls[num_ctrls] = NULL;
+                                               } else
 #endif
-                                                               send_ldap_result( conn, op, rc=LDAP_OTHER,
-                                                                       NULL, "internal error", NULL, NULL );
-                                                               goto done;
-                                                       }
 
-                                                       ber_dupbv( &ctrls[0]->ldctl_value, bv );
-                                                       
-                                                       result = send_search_entry( be, conn, op,
-                                                               e, attrs, attrsonly, ctrls);
-
-                                                       ch_free( ctrls[0]->ldctl_value.bv_val );
-                                                       ch_free( ctrls[0] );
-                                                       ber_free( ber, 1 );
-                                                       ber_bvfree( bv );
-                                               } else
-#endif /* LDAP_CLIENT_UPDATE */
                                                {
                                                        result = send_search_entry( be, conn, op,
                                                                e, attrs, attrsonly, NULL);
@@ -755,61 +830,44 @@ loop_continue:
 
 #ifdef LDAP_CLIENT_UPDATE
        if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
-               int ret;
-               LDAPControl *ctrls[2];
-               BerElement *ber = ber_alloc_t( LBER_USE_DER );
-               struct berval *bv;
-
-               if ( ber == NULL ) {
-#ifdef NEW_LOGGING
-                       LDAP_LOG ( OPERATION, RESULTS, 
-                               "bdb_search: ber_alloc_t failed\n", 0, 0, 0 );
-#else
-                       Debug( LDAP_DEBUG_TRACE, "bdb_search: ber_alloc_t failed\n",
-                               0, 0, 0 );
-#endif
-                       send_ldap_result( conn, op, rc=LDAP_OTHER,
-                               NULL, "internal error", NULL, NULL );
-                       goto done;
-               }
-
-               ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) );
-               ctrls[1] = NULL;
+               bdb_build_lcup_done_ctrl( conn, op, ctrls, num_ctrls++, &latest_entrycsn_bv );
 
-               ber_printf( ber, "{sO", LCUP_COOKIE_OID, &latest_entrycsn_bv );
-               ber_printf( ber, "N}" );
+               send_search_result( conn, op,
+                               v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
+                               NULL, NULL, v2refs, ctrls, nentries );
 
-               ctrls[0]->ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE_DONE;
-               ctrls[0]->ldctl_iscritical = op->o_clientupdate;
-               ret = ber_flatten( ber, &bv );
+               ch_free( latest_entrycsn_bv.bv_val );
+               latest_entrycsn_bv.bv_val = NULL;
 
-               if ( ret < 0 ) {
-#ifdef NEW_LOGGING
-                       LDAP_LOG ( OPERATION, RESULTS, 
-                               "bdb_search: ber_flatten failed\n", 0, 0, 0 );
-#else
-                       Debug( LDAP_DEBUG_TRACE, "bdb_search: ber_flatten failed\n",
-                               0, 0, 0 );
+               if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+                               ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+               ch_free( ctrls[--num_ctrls] );
+               ctrls[num_ctrls] = NULL;
+       } else
 #endif
-                       send_ldap_result( conn, op, rc=LDAP_OTHER,
-                               NULL, "internal error", NULL, NULL );
-                       goto done;
+#ifdef LDAP_SYNC
+       if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+               if ( op->o_sync_mode & SLAP_SYNC_PERSIST ) {
+                       /* refreshAndPersist mode */
+                       bdb_send_ldap_intermediate( conn, op,
+                               LDAP_SUCCESS, NULL, NULL, NULL, LDAP_SYNC_INFO,
+                               LDAP_SYNC_REFRESH_DONE, &latest_entrycsn_bv, NULL );
+               } else {
+                       /* refreshOnly mode */
+                       bdb_build_sync_done_ctrl( conn, op, ctrls, num_ctrls++, 1, &latest_entrycsn_bv );
+                       send_search_result( conn, op,
+                                       v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
+                                       NULL, NULL, v2refs, ctrls, nentries );
+                       if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+                               ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+                       ch_free( ctrls[--num_ctrls] );
+                       ctrls[num_ctrls] = NULL;
                }
 
-               ber_dupbv( &ctrls[0]->ldctl_value, bv );
-
-               send_search_result( conn, op,
-                       v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
-                       NULL, NULL, v2refs, ctrls, nentries );
-
                ch_free( latest_entrycsn_bv.bv_val );
                latest_entrycsn_bv.bv_val = NULL;
-               ch_free( ctrls[0]->ldctl_value.bv_val );
-               ch_free( ctrls[0] );
-               ber_free( ber, 1 );
-               ber_bvfree( bv );
        } else
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
        {
                send_search_result( conn, op,
                        v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
@@ -834,7 +892,21 @@ done:
                        ch_free( csnfge.f_av_value.bv_val );
                }
        }
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+       else
+#endif
+#ifdef LDAP_SYNC
+       if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+               if ( csnfeq.f_ava != NULL && csnfeq.f_av_value.bv_val != NULL ) {
+                       ch_free( csnfeq.f_av_value.bv_val );
+               }
+
+               if ( csnfge.f_ava != NULL && csnfge.f_av_value.bv_val != NULL ) {
+                       ch_free( csnfge.f_av_value.bv_val );
+               }
+       }
+#endif
 
        LOCK_ID_FREE (bdb->bi_dbenv, locker );
 
@@ -1066,3 +1138,391 @@ static int search_candidates(
        return rc;
 }
 
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+static void
+send_pagerequest_response( 
+       Connection      *conn,
+       Operation       *op,
+       ID              lastid,
+       int             nentries,
+       int             tentries )
+{
+       LDAPControl     ctrl, *ctrls[2];
+       char berbuf[LBER_ELEMENT_SIZEOF];
+       BerElement      *ber = (BerElement *)berbuf;
+       struct berval   cookie = { 0, NULL };
+       PagedResultsCookie respcookie;
+
+#ifdef NEW_LOGGING
+       LDAP_LOG ( OPERATION, ENTRY,
+               "send_pagerequest_response: lastid: (0x%08lx) "
+               "nentries: (0x%081x)\n", 
+               lastid, nentries, NULL );
+#else
+       Debug(LDAP_DEBUG_ARGS, "send_pagerequest_response: lastid: (0x%08lx) "
+                       "nentries: (0x%081x)\n", lastid, nentries, NULL );
+#endif
+
+       ctrl.ldctl_value.bv_val = NULL;
+       ctrls[0] = &ctrl;
+       ctrls[1] = NULL;
+
+       ber_init2( ber, NULL, LBER_USE_DER );
+
+       respcookie = ( PagedResultsCookie )lastid;
+       conn->c_pagedresults_state.ps_cookie = respcookie;
+       cookie.bv_len = sizeof( respcookie );
+       cookie.bv_val = (char *)&respcookie;
+
+       /*
+        * FIXME: we should consider sending an estimate of the entries
+        * left, after appropriate security check is done
+        */
+       ber_printf( ber, "{iO}", tentries, &cookie ); 
+
+       if ( ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 ) == -1 ) {
+               goto done;
+       }
+
+       ctrls[0]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
+       ctrls[0]->ldctl_iscritical = 0;
+
+       send_search_result( conn, op,
+               LDAP_SUCCESS,
+               NULL, NULL, NULL, ctrls, nentries );
+
+done:
+       (void) ber_free_buf( ber );
+}                      
+#endif
+
+#ifdef LDAP_CLIENT_UPDATE
+int
+bdb_build_lcup_update_ctrl(
+       Connection      *conn,
+       Operation       *op,
+       Entry           *e,
+       int             entry_count,
+       LDAPControl     **ctrls,
+       int             num_ctrls,
+       struct berval   *latest_entrycsn_bv,
+       int             isdeleted       )
+{
+       Attribute* a;
+       int ret;
+       int res;
+       int rc;
+       const char *text = NULL;
+
+       char berbuf[LBER_ELEMENT_SIZEOF];
+       BerElement *ber = (BerElement *)berbuf;
+
+       struct berval entrycsn_bv = { 0, NULL };
+
+       ber_init2( ber, 0, LBER_USE_DER );
+
+       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+               AttributeDescription *desc = a->a_desc;
+               if ( desc == slap_schema.si_ad_entryCSN ) {
+                       ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
+                       if ( latest_entrycsn_bv->bv_val == NULL ) {
+                               ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
+                       } else {
+                               res = value_match( &ret, desc,
+                                       desc->ad_type->sat_ordering,
+                                       SLAP_MR_ASSERTION_SYNTAX_MATCH,
+                                       &entrycsn_bv, latest_entrycsn_bv, &text );
+                               if ( res != LDAP_SUCCESS ) {
+                                       ret = 0;
+#ifdef NEW_LOGGING
+                                       LDAP_LOG ( OPERATION, RESULTS, 
+                                               "bdb_search: value_match failed\n",
+                                               0, 0, 0 );
+#else
+                                       Debug( LDAP_DEBUG_TRACE,
+                                               "bdb_search: value_match failed\n",
+                                               0, 0, 0 );
+#endif
+                               }
+
+                               if ( ret > 0 ) {
+                                       ch_free( latest_entrycsn_bv->bv_val );
+                                       latest_entrycsn_bv->bv_val = NULL;
+                                       ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
+                               }
+                       }
+               }
+       }
+
+       if ( entry_count % op->o_clientupdate_interval == 0 )
+               ber_printf( ber,
+                       "{bb{sON}N}",
+                       SLAP_LCUP_STATE_UPDATE_FALSE,
+                       isdeleted,
+                       LDAP_LCUP_COOKIE_OID, &entrycsn_bv );
+       else /* Do not send cookie */
+               ber_printf( ber,
+                       "{bbN}",
+                       SLAP_LCUP_STATE_UPDATE_FALSE,
+                       isdeleted );
+
+       ch_free( entrycsn_bv.bv_val );
+       entrycsn_bv.bv_val = NULL;
+
+       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE;
+       ctrls[num_ctrls]->ldctl_iscritical = op->o_clientupdate;
+       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+       ber_free_buf( ber );
+
+       if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS, 
+                       "bdb_build_lcup_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "bdb_build_lcup_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#endif
+               send_ldap_result( conn, op, rc=LDAP_OTHER,
+                       NULL, "internal error", NULL, NULL );
+               return ret;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+int
+bdb_build_lcup_done_ctrl(
+       Connection      *conn,
+       Operation       *op,
+       LDAPControl     **ctrls,
+       int             num_ctrls,
+       struct berval   *latest_entrycsn_bv     )
+{
+       int ret, rc;
+       char berbuf[LBER_ELEMENT_SIZEOF];
+       BerElement *ber = (BerElement *)berbuf;
+
+       ber_init2( ber, NULL, LBER_USE_DER );
+
+       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+       ber_printf( ber, "{sO", LDAP_LCUP_COOKIE_OID, latest_entrycsn_bv );
+       ber_printf( ber, "N}" );
+
+       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE_DONE;
+       ctrls[num_ctrls]->ldctl_iscritical = op->o_clientupdate;
+       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+       ber_free_buf( ber );
+
+       if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS, 
+                       "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n", 0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#endif
+               send_ldap_result( conn, op, rc=LDAP_OTHER,
+                       NULL, "internal error", NULL, NULL );
+               return ret;
+       }
+
+       return LDAP_SUCCESS;
+}
+#endif
+
+#ifdef LDAP_SYNC
+int
+bdb_build_sync_state_ctrl(
+       Connection      *conn,
+       Operation       *op,
+       Entry           *e,
+       int             entry_sync_state,
+       LDAPControl     **ctrls,
+       int             num_ctrls,
+       int             send_cookie,
+       struct berval   *latest_entrycsn_bv     )
+{
+       Attribute* a;
+       int ret;
+       int res;
+       int rc;
+       const char *text = NULL;
+
+       char berbuf[LBER_ELEMENT_SIZEOF];
+       BerElement *ber = (BerElement *)berbuf;
+
+       struct berval entryuuid_bv      = { 0, NULL };
+       struct berval entrycsn_bv       = { 0, NULL };
+
+       ber_init2( ber, 0, LBER_USE_DER );
+
+       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+       for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+               AttributeDescription *desc = a->a_desc;
+               if ( desc == slap_schema.si_ad_entryCSN ) {
+                       ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
+                       if ( latest_entrycsn_bv->bv_val == NULL ) {
+                               ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
+                       } else {
+                               res = value_match( &ret, desc,
+                                               desc->ad_type->sat_ordering,
+                                               SLAP_MR_ASSERTION_SYNTAX_MATCH,
+                                               &entrycsn_bv, latest_entrycsn_bv, &text );
+                               if ( res != LDAP_SUCCESS ) {
+                                       ret = 0;
+#ifdef NEW_LOGGING
+                                       LDAP_LOG ( OPERATION, RESULTS,
+                                                       "bdb_search: value_match failed\n",
+                                                       0, 0, 0 );
+#else
+                                       Debug( LDAP_DEBUG_TRACE,
+                                                       "bdb_search: value_match failed\n",
+                                                       0, 0, 0 );
+#endif
+                               }
+                               if ( ret > 0 ) {
+                                       ch_free( latest_entrycsn_bv->bv_val );
+                                       latest_entrycsn_bv->bv_val = NULL;
+                                       ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
+                               }
+                       }
+               } else if ( desc == slap_schema.si_ad_entryUUID ) {
+                       ber_dupbv( &entryuuid_bv, &a->a_vals[0] );
+               }
+       }
+
+       if ( send_cookie )
+               ber_printf( ber, "{eOON}", entry_sync_state, &entryuuid_bv, &entrycsn_bv );
+       else
+               ber_printf( ber, "{eON}", entry_sync_state, &entryuuid_bv );
+
+       ch_free( entrycsn_bv.bv_val );
+       entrycsn_bv.bv_val = NULL;
+       ch_free( entryuuid_bv.bv_val );
+       entryuuid_bv.bv_val = NULL;
+
+       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
+       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
+       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+       ber_free_buf( ber );
+
+       if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS, 
+                       "bdb_build_sync_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "bdb_build_sync_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#endif
+               send_ldap_result( conn, op, rc=LDAP_OTHER,
+                       NULL, "internal error", NULL, NULL );
+               return ret;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+int
+bdb_build_sync_done_ctrl(
+       Connection      *conn,
+       Operation       *op,
+       LDAPControl     **ctrls,
+       int             num_ctrls,
+       int             send_cookie,
+       struct berval   *latest_entrycsn_bv     )
+{
+       int ret,rc;
+       char berbuf[LBER_ELEMENT_SIZEOF];
+       BerElement *ber = (BerElement *)berbuf;
+
+       ber_init2( ber, NULL, LBER_USE_DER );
+
+       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+       if ( send_cookie ) {
+               ber_printf( ber, "{ON}", latest_entrycsn_bv );
+       } else {
+               ber_printf( ber, "{N}" );
+       }
+
+       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE;
+       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
+       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+       ber_free_buf( ber );
+
+       if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS, 
+                       "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n", 0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#endif
+               send_ldap_result( conn, op, rc=LDAP_OTHER,
+                       NULL, "internal error", NULL, NULL );
+               return ret;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+int
+bdb_send_ldap_intermediate(
+       Connection  *conn,
+       Operation   *op,
+       ber_int_t   err,
+       const char  *matched,
+       const char  *text,
+       BerVarray   refs,
+       const char  *rspoid,
+       int         state,
+       struct berval *cookie,
+       LDAPControl **ctrls     )
+{
+       char berbuf[LBER_ELEMENT_SIZEOF];
+       BerElement *ber = (BerElement *)berbuf;
+       struct berval rspdata;
+
+       int ret, rc;
+
+       ber_init2( ber, NULL, LBER_USE_DER );
+
+       if ( cookie == NULL )
+               ber_printf( ber, "{eN}", state );
+       else
+               ber_printf( ber, "{eON}", state, cookie );
+
+       ret = ber_flatten2( ber, &rspdata, 0 );
+
+       if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG ( OPERATION, RESULTS, 
+                       "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n", 0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n",
+                       0, 0, 0 );
+#endif
+               send_ldap_result( conn, op, rc=LDAP_OTHER,
+                       NULL, "internal error", NULL, NULL );
+               return ret;
+       }
+
+       send_ldap_intermediate_resp( conn, op, err, matched, text, refs, rspoid, &rspdata, ctrls );
+
+       ber_free_buf( ber );
+
+       return LDAP_SUCCESS;
+}
+#endif
index 21ada672c311ad7d6519cc708c771583fd47dd78..f17451ad7aeb902dc45ccbc7ef8b8ee0855004da 100644 (file)
@@ -1,7 +1,7 @@
 /* add.c - ldap backend add function */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
@@ -138,8 +138,9 @@ ldap_back_add(
                        continue;
                }
 
-               ldap_back_map(&li->at_map, &a->a_desc->ad_cname, &mapped, 0);
-               if (mapped.bv_val == NULL) {
+               ldap_back_map(&li->at_map, &a->a_desc->ad_cname, &mapped,
+                               BACKLDAP_MAP);
+               if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
                        continue;
                }
 
diff --git a/servers/slapd/back-ldap/attribute.c b/servers/slapd/back-ldap/attribute.c
new file mode 100644 (file)
index 0000000..81f7788
--- /dev/null
@@ -0,0 +1,139 @@
+/* group.c - ldap backend acl group routine */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-ldap.h"
+
+
+/* return 0 IFF we can retrieve the attributes
+ * of entry with ndn
+ */
+int
+ldap_back_attribute(
+       Backend *be,
+       Connection *conn,
+       Operation *op,
+       Entry   *target,
+       struct berval   *ndn,
+       AttributeDescription *entry_at,
+       BerVarray *vals
+)
+{
+       struct ldapinfo *li = (struct ldapinfo *) be->be_private;    
+       int rc = 1, i, j, count, is_oc;
+       Attribute *attr = NULL;
+       BerVarray abv, v;
+       struct berval mapped = { 0, NULL };
+       char **vs = NULL;
+       LDAPMessage     *result = NULL, *e = NULL;
+       char *gattr[2];
+       LDAP *ld = NULL;
+
+       *vals = NULL;
+       if (target != NULL && dn_match( &target->e_nname, ndn )) {
+               /* we already have a copy of the entry */
+               /* attribute and objectclass mapping has already been done */
+               if ((attr = attr_find(target->e_attrs, entry_at)) == NULL)
+                       return(1);
+
+               for ( count = 0; attr->a_vals[count].bv_val != NULL; count++ ) { }
+               v = (BerVarray) ch_calloc( (count + 1), sizeof(struct berval) );
+               if (v != NULL) {
+                       for ( j = 0, abv = attr->a_vals; --count >= 0; abv++ ) {
+                               if ( abv->bv_len > 0 ) {
+                                       ber_dupbv( &v[j], abv );
+                                       if( v[j].bv_val == NULL )
+                                               break;
+                               }
+                       }
+                       v[j].bv_val = NULL;
+                       *vals = v;
+                       return 0;
+               }
+
+       }
+       ldap_back_map(&li->at_map, &entry_at->ad_cname, &mapped, BACKLDAP_MAP);
+       if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
+               return 1;
+       }
+
+       if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) {
+               return 1;
+       }
+
+       if (ldap_bind_s(ld, li->binddn, li->bindpw, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) {
+               goto cleanup;
+       }
+
+       gattr[0] = mapped.bv_val;
+       gattr[1] = NULL;
+       if (ldap_search_ext_s(ld, ndn->bv_val, LDAP_SCOPE_BASE, "(objectclass=*)",
+                               gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
+                               LDAP_NO_LIMIT, &result) != LDAP_SUCCESS)
+       {
+               goto cleanup;
+       }
+
+       if ((e = ldap_first_entry(ld, result)) == NULL) {
+               goto cleanup;
+       }
+               
+       vs = ldap_get_values(ld, e, mapped.bv_val);
+       if (vs == NULL) {
+               goto cleanup;
+       }
+
+       for ( count = 0; vs[count] != NULL; count++ ) { }
+       v = (BerVarray) ch_calloc( (count + 1), sizeof(struct berval) );
+       if (v == NULL) {
+               goto cleanup;
+       }
+
+       is_oc = (strcasecmp("objectclass", mapped.bv_val) == 0);
+       for ( i = 0, j = 0; i < count; i++) {
+               ber_str2bv(vs[i], 0, 0, &v[j] );
+               if (!is_oc) {
+                       if( v[j].bv_val == NULL )
+                               ch_free(vs[i]);
+                       else
+                               j++;
+               } else {
+                       ldap_back_map(&li->oc_map, &v[j], &mapped,
+                                       BACKLDAP_REMAP);
+                       if (mapped.bv_val && mapped.bv_val[0] != '\0') {
+                               ber_dupbv( &v[j], &mapped );
+                               if (v[j].bv_val)
+                                       j++;
+                       }
+                       ch_free(vs[i]);
+               }
+       }
+       v[j].bv_val = NULL;
+       *vals = v;
+       rc = 0;
+       ch_free(vs);
+       vs = NULL;
+
+cleanup:
+       if (vs) {
+               ldap_value_free(vs);
+       }
+       if (result) {
+               ldap_msgfree(result);
+       }
+       ldap_unbind(ld);
+
+       return(rc);
+}
+
index 3145ddd881ea556d9f375c72dcba0d8cb12477d1..eb56fce7cf59dbb51051ca49589007b1499a6b64 100644 (file)
@@ -1,7 +1,7 @@
 /* back-ldap.h - ldap backend header file */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
@@ -106,6 +106,8 @@ int mapping_dup (void *, void *);
 void ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping ** );
 void ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *m,
        int remap );
+#define BACKLDAP_MAP   0
+#define BACKLDAP_REMAP 1
 char *
 ldap_back_map_filter(
                struct ldapmap *at_map,
@@ -120,7 +122,7 @@ ldap_back_map_attrs(
                int remap
 );
 
-extern void mapping_free ( struct ldapmapping *mapping );
+extern void mapping_free ( void *mapping );
 
 #ifdef ENABLE_REWRITE
 extern int suffix_massage_config( struct rewrite_info *info,
@@ -131,4 +133,4 @@ extern int ldap_dnattr_rewrite( struct rewrite_info *rwinfo, BerVarray a_vals, v
 
 LDAP_END_DECL
 
-#endif
+#endif /* SLAPD_LDAP_H */
index e4c966f9e97808d476eb507406f5672c73e498b7..d8767c6f9142948a493b56ab12edce0d0f50348f 100644 (file)
@@ -1,7 +1,7 @@
 /* compare.c - ldap backend compare function */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
@@ -100,13 +100,20 @@ ldap_back_compare(
        }
 #endif /* !ENABLE_REWRITE */
 
-       ldap_back_map(&li->oc_map, &ava->aa_desc->ad_cname, &mapped_oc, 0);
-       if (mapped_oc.bv_val == NULL)
-               return( -1 );
-
-       ldap_back_map(&li->at_map, &ava->aa_value, &mapped_at, 0);
-       if (mapped_at.bv_val == NULL)
-               return( -1 );
+       if ( ava->aa_desc == slap_schema.si_ad_objectClass ) {
+               ldap_back_map(&li->oc_map, &ava->aa_desc->ad_cname, &mapped_oc,
+                               BACKLDAP_MAP);
+               if (mapped_oc.bv_val == NULL || mapped_oc.bv_val[0] == '\0') {
+                       return( -1 );
+               }
+               
+       } else {
+               ldap_back_map(&li->at_map, &ava->aa_value, &mapped_at, 
+                               BACKLDAP_MAP);
+               if (mapped_at.bv_val == NULL || mapped_at.bv_val[0] == '\0') {
+                       return( -1 );
+               }
+       }
 
        ldap_compare_s( lc->ld, mdn.bv_val, mapped_oc.bv_val, mapped_at.bv_val );
 
index 42e44659bfd049f8a02f4155f16d5227871b39f9..13e49922d3dda8685e3b13895ad8031cb5b4e628 100644 (file)
@@ -1,7 +1,7 @@
 /* config.c - ldap backend configuration file routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
@@ -444,7 +444,7 @@ suffix_massage_config(
                         */
                        return -1;
 
-               } else if ( len >= sizeof( vbuf_ ) ) {
+               } else if ( len >= (int)sizeof( vbuf_ ) ) {
                        /* 
                         * C99: snprintf returns the required size 
                         */
@@ -459,7 +459,7 @@ suffix_massage_config(
                if ( len == -1 ) {
                        return -1;
 
-               } else if ( len >= sizeof( rbuf_ ) ) {
+               } else if ( len >= (int)sizeof( rbuf_ ) ) {
                        rbuf = ch_malloc( len + 1 );
                        len = snprintf( rbuf, sizeof( rbuf_ ), "%%1%s)%%2", 
                                        nrnc->bv_val );
index 8448e87d8aabc3ec06b52b34bb517b3ee2e1d484..79e67c60959ab42058fb4e4d44c04af03d00c7ce 100644 (file)
@@ -1,7 +1,7 @@
 /* group.c - ldap backend acl group routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -154,11 +154,13 @@ ldap_back_group(
        }
 #endif /* !ENABLE_REWRITE */
 
-       ldap_back_map(&li->oc_map, &group_oc_name, &group_oc_name, 0);
-       if (group_oc_name.bv_val == NULL)
+       ldap_back_map(&li->oc_map, &group_oc_name, &group_oc_name,
+                       BACKLDAP_MAP);
+       if (group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0')
                goto cleanup;
-       ldap_back_map(&li->at_map, &group_at_name, &group_at_name, 0);
-       if (group_at_name.bv_val == NULL)
+       ldap_back_map(&li->at_map, &group_at_name, &group_at_name,
+                       BACKLDAP_MAP);
+       if (group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0')
                goto cleanup;
 
        filter = ch_malloc(sizeof("(&(objectclass=)(=))")
index 6cc3078363d59777a8dc757bf4b5911a8720fe70..5a4b1e2798a966cbb41c240e1220fcd36ecd0999 100644 (file)
@@ -1,7 +1,7 @@
 /* init.c - initialize ldap backend */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
@@ -131,9 +131,10 @@ ldap_back_db_init(
 
 static void
 conn_free( 
-       struct ldapconn *lc
+       void *v_lc
 )
 {
+       struct ldapconn *lc = v_lc;
        ldap_unbind( lc->ld );
        if ( lc->bound_dn.bv_val ) {
                ch_free( lc->bound_dn.bv_val );
@@ -145,8 +146,9 @@ conn_free(
 }
 
 void
-mapping_free ( struct ldapmapping *mapping )
+mapping_free( void *v_mapping )
 {
+       struct ldapmapping *mapping = v_mapping;
        ch_free( mapping->src.bv_val );
        ch_free( mapping->dst.bv_val );
        ch_free( mapping );
@@ -177,7 +179,7 @@ ldap_back_db_destroy(
                        li->bindpw = NULL;
                }
                 if (li->conntree) {
-                       avl_free( li->conntree, (AVL_FREE) conn_free );
+                       avl_free( li->conntree, conn_free );
                }
 #ifdef ENABLE_REWRITE
                if (li->rwinfo) {
@@ -190,9 +192,9 @@ ldap_back_db_destroy(
 #endif /* !ENABLE_REWRITE */
 
                avl_free( li->oc_map.remap, NULL );
-               avl_free( li->oc_map.map, (AVL_FREE) mapping_free );
+               avl_free( li->oc_map.map, mapping_free );
                avl_free( li->at_map.remap, NULL );
-               avl_free( li->at_map.map, (AVL_FREE) mapping_free );
+               avl_free( li->at_map.map, mapping_free );
                
                ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
                ldap_pvt_thread_mutex_destroy( &li->conn_mutex );
index 7bf1e470a1cd057b603e2a0941a489ea759a9ba1..9a5fb497da48dbe9b5eb77b12904c13795e3a4af 100644 (file)
@@ -1,6 +1,6 @@
 /* map.c - ldap backend mapping routines */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
@@ -97,7 +97,7 @@ ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
        Avlnode *tree;
        struct ldapmapping *mapping, fmapping;
 
-       if (remap)
+       if (remap == BACKLDAP_REMAP)
                tree = map->remap;
        else
                tree = map->map;
@@ -174,10 +174,11 @@ ldap_back_map_filter(
                                tmp.bv_len = p - q;
                                tmp.bv_val = q;
                                ldap_back_map(at_map, &tmp, &m, remap);
-                               if (m.bv_val == NULL)
+                               if (m.bv_val == NULL || m.bv_val[0] == '\0') {
                                        ldap_back_map(oc_map, &tmp, &m, remap);
-                               if (m.bv_val == NULL) {
-                                       m = tmp;
+                                       if (m.bv_val == NULL || m.bv_val[0] == '\0') {
+                                               m = tmp;
+                                       }
                                }
                                extra += p - q;
                                plen = m.bv_len;
@@ -233,7 +234,7 @@ ldap_back_map_attrs(
 
        for (i = j = 0; an[i].an_name.bv_val; i++) {
                ldap_back_map(at_map, &an[i].an_name, &mapped, remap);
-               if (mapped.bv_val != NULL)
+               if (mapped.bv_val != NULL && mapped.bv_val != '\0')
                        na[j++] = mapped.bv_val;
        }
        if (j == 0 && i != 0)
index 8deeeaa88833d7591af263317d34c7a71e3c5eb9..5cb19e5175acf2a71b6f738bb7afb7904fb017f5 100644 (file)
@@ -1,7 +1,7 @@
 /* modify.c - ldap backend modify function */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
@@ -118,8 +118,9 @@ ldap_back_modify(
                        continue;
                }
 
-               ldap_back_map(&li->at_map, &ml->sml_desc->ad_cname, &mapped, 0);
-               if (mapped.bv_val == NULL) {
+               ldap_back_map(&li->at_map, &ml->sml_desc->ad_cname, &mapped,
+                               BACKLDAP_MAP);
+               if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
                        continue;
                }
 
index fe25fdc8dce32a8bb906665e1ebcb5f0c4ac27cc..41b397a9da22dd2cdef2c9535414219f59671768 100644 (file)
@@ -1,7 +1,7 @@
 /* search.c - ldap backend search function */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
@@ -235,7 +235,7 @@ ldap_back_search(
 #else /* !ENABLE_REWRITE */
                        filterstr,
 #endif /* !ENABLE_REWRITE */
-                       0);
+                       BACKLDAP_MAP);
        if ( mapped_filter == NULL ) {
 #ifdef ENABLE_REWRITE
                mapped_filter = mfilter.bv_val;
@@ -250,7 +250,7 @@ ldap_back_search(
        }
 #endif /* ENABLE_REWRITE */
 
-       mapped_attrs = ldap_back_map_attrs(&li->at_map, attrs, 0);
+       mapped_attrs = ldap_back_map_attrs(&li->at_map, attrs, BACKLDAP_MAP);
        if ( mapped_attrs == NULL && attrs) {
                for (count=0; attrs[count].an_name.bv_val; count++);
                mapped_attrs = ch_malloc( (count+1) * sizeof(char *));
@@ -491,8 +491,8 @@ ldap_send_entry(
        attrp = &ent.e_attrs;
 
        while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
-               ldap_back_map(&li->at_map, &a, &mapped, 1);
-               if (mapped.bv_val == NULL)
+               ldap_back_map(&li->at_map, &a, &mapped, BACKLDAP_REMAP);
+               if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0')
                        continue;
                attr = (Attribute *)ch_malloc( sizeof(Attribute) );
                if (attr == NULL)
@@ -536,8 +536,9 @@ ldap_send_entry(
 
                        for ( last = 0; attr->a_vals[last].bv_val; last++ ) ;
                        for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
-                               ldap_back_map(&li->oc_map, bv, &mapped, 1);
-                               if (mapped.bv_val == NULL) {
+                               ldap_back_map(&li->oc_map, bv, &mapped,
+                                               BACKLDAP_REMAP);
+                               if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
                                        LBER_FREE(bv->bv_val);
                                        bv->bv_val = NULL;
                                        if (--last < 0)
index a5aa5f1f9245f117b8e9b1b9e73a2e7f301f0f93..93d2bd4f8b7149da54e90efabb71d6a8ddbedfec 100644 (file)
@@ -1,7 +1,7 @@
 /* unbind.c - ldap backend unbind function */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* This is an altered version */
index 47022cfe40bcfb7e6409807a9ce781234b7cbcc7..15b3055e91f4eb2b0355969ae1afc7f330bbfa89 100644 (file)
@@ -1,7 +1,7 @@
 /* attr.c - backend routines for dealing with attributes */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -23,19 +23,22 @@ typedef struct ldbm_attrinfo {
 
 static int
 ainfo_type_cmp(
-       AttributeDescription *desc,
-    AttrInfo   *a
+       const void *v_desc,
+       const void *v_a
 )
 {
+       const AttributeDescription *desc = v_desc;
+       const AttrInfo             *a    = v_a;
        return desc - a->ai_desc;
 }
 
 static int
 ainfo_cmp(
-    AttrInfo   *a,
-    AttrInfo   *b
+       const void      *v_a,
+       const void      *v_b
 )
 {
+       const AttrInfo *a = v_a, *b = v_b;
        return a->ai_desc - b->ai_desc;
 }
 
@@ -47,8 +50,7 @@ attr_mask(
 {
        AttrInfo        *a;
 
-       a = (AttrInfo *) avl_find( li->li_attrs, desc,
-           (AVL_CMP) ainfo_type_cmp );
+       a = avl_find( li->li_attrs, desc, ainfo_type_cmp );
        
        *indexmask = a != NULL ? a->ai_indexmask : 0;
 }
@@ -195,7 +197,7 @@ attr_index_config(
                a->ai_indexmask = mask;
 
                rc = avl_insert( &li->li_attrs, (caddr_t) a,
-                       (AVL_CMP) ainfo_cmp, (AVL_DUP) avl_dup_error );
+                                ainfo_cmp, avl_dup_error );
 
                if( rc ) {
                        fprintf( stderr, "%s: line %d: duplicate index definition "
index 766e31c0c693bcfbb1d56c3a8de190acddcd8ff4..e95124f4b142a8f209aaad056b5c806c425893ac 100644 (file)
@@ -1,7 +1,7 @@
 /* bind.c - ldbm backend bind and unbind routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -269,7 +269,7 @@ return_results:;
        cache_return_entry_r( &li->li_cache, e );
        ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
 
-       /* front end with send result on success (rc==0) */
+       /* front end will send result on success (rc==0) */
        return( rc );
 }
 
index 4a26488a4e8bf3831a7ab06e4f6808fb1458f110..c6f9b237a72c6f2f36d598e32e5783c09276c500 100644 (file)
@@ -1,7 +1,7 @@
 /* cache.c - routines to maintain an in-core cache of entries */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -244,7 +244,7 @@ cache_add_entry_rw(
        }
 
        if ( avl_insert( &cache->c_dntree, (caddr_t) e,
-               (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
+                        entry_dn_cmp, avl_dup_error ) != 0 )
        {
                /* free cache mutex */
                ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
@@ -266,7 +266,7 @@ cache_add_entry_rw(
 
        /* id tree */
        if ( avl_insert( &cache->c_idtree, (caddr_t) e,
-               (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
+                        entry_id_cmp, avl_dup_error ) != 0 )
        {
 #ifdef NEW_LOGGING
                LDAP_LOG( CACHE, DETAIL1, 
@@ -280,7 +280,7 @@ cache_add_entry_rw(
 
                /* delete from dn tree inserted above */
                if ( avl_delete( &cache->c_dntree, (caddr_t) e,
-                       (AVL_CMP) entry_dn_cmp ) == NULL )
+                                entry_dn_cmp ) == NULL )
                {
 #ifdef NEW_LOGGING
                        LDAP_LOG( CACHE, INFO, 
@@ -368,7 +368,7 @@ cache_update_entry(
        assert( e->e_private );
 
        if ( avl_insert( &cache->c_dntree, (caddr_t) e,
-               (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
+                        entry_dn_cmp, avl_dup_error ) != 0 )
        {
 #ifdef NEW_LOGGING
                LDAP_LOG( CACHE, DETAIL1, 
@@ -387,7 +387,7 @@ cache_update_entry(
 
        /* id tree */
        if ( avl_insert( &cache->c_idtree, (caddr_t) e,
-               (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
+                        entry_id_cmp, avl_dup_error ) != 0 )
        {
 #ifdef NEW_LOGGING
                LDAP_LOG( CACHE, DETAIL1, 
@@ -401,7 +401,7 @@ cache_update_entry(
 
                /* delete from dn tree inserted above */
                if ( avl_delete( &cache->c_dntree, (caddr_t) e,
-                       (AVL_CMP) entry_dn_cmp ) == NULL )
+                                entry_dn_cmp ) == NULL )
                {
 #ifdef NEW_LOGGING
                        LDAP_LOG( CACHE, INFO, 
@@ -484,7 +484,7 @@ try_again:
        ldap_pvt_thread_mutex_lock( &cache->c_mutex );
 
        if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e,
-               (AVL_CMP) entry_dn_cmp )) != NULL )
+                                      entry_dn_cmp )) != NULL )
        {
                int state;
                count++;
@@ -571,7 +571,7 @@ try_again:
        ldap_pvt_thread_mutex_lock( &cache->c_mutex );
 
        if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e,
-               (AVL_CMP) entry_id_cmp )) != NULL )
+                                      entry_id_cmp )) != NULL )
        {
                int state;
                ID      ep_id;
@@ -683,15 +683,13 @@ cache_delete_entry_internal(
        int rc = 0;     /* return code */
 
        /* dn tree */
-       if ( avl_delete( &cache->c_dntree, (caddr_t) e, (AVL_CMP) entry_dn_cmp )
-               == NULL )
+       if ( avl_delete( &cache->c_dntree, (caddr_t) e, entry_dn_cmp ) == NULL )
        {
                rc = -1;
        }
 
        /* id tree */
-       if ( avl_delete( &cache->c_idtree, (caddr_t) e, (AVL_CMP) entry_id_cmp )
-               == NULL )
+       if ( avl_delete( &cache->c_idtree, (caddr_t) e, entry_id_cmp ) == NULL )
        {
                rc = -1;
        }
index 811fbe7441b3d4e9de6d43d11cb744f952141483..921a02f3823cb0bb362003620e95c02d8b5b20eb 100644 (file)
@@ -1,7 +1,7 @@
 /* ldbmcache.c - maintain a cache of open ldbm files */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -325,6 +325,7 @@ ldbm_cache_sync( Backend *be )
        ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
 }
 
+#if 0 /* macro in proto-back-ldbm.h */
 Datum
 ldbm_cache_fetch(
     DBCache    *db,
@@ -333,6 +334,7 @@ ldbm_cache_fetch(
 {
        return ldbm_fetch( db->dbc_db, key );
 }
+#endif /* 0 */
 
 int
 ldbm_cache_store(
index 93b40b1dd446b58d1b86fef699e56dabb107bd30..0f3107d85b8c7604bc4ef71851f6a3b89db9c5a7 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -43,9 +43,7 @@ extern BI_acl_attribute       ldbm_back_attribute;
 
 extern BI_operational  ldbm_back_operational;
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
 extern BI_has_subordinates     ldbm_back_hasSubordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
 /* hooks for slap tools */
 extern BI_tool_entry_open      ldbm_tool_entry_open;
index c59145e296053538b536034e41210c794b75d965..ff07968cd9b505e6edf0b394ff5851387213f42b 100644 (file)
@@ -1,7 +1,7 @@
 /* filterindex.c - generate the list of candidate entries from a filter */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -219,7 +219,7 @@ presence_candidates(
        int rc;
        char *dbname;
        slap_mask_t mask;
-       struct berval prefix = {0};
+       struct berval prefix = {0, NULL};
 
 #ifdef NEW_LOGGING
        LDAP_LOG( FILTER, ENTRY, "presence_candidates: enter\n", 0, 0, 0 );
@@ -333,7 +333,7 @@ equality_candidates(
        int rc;
        char *dbname;
        slap_mask_t mask;
-       struct berval prefix = {0};
+       struct berval prefix = {0, NULL};
        struct berval *keys = NULL;
        MatchingRule *mr;
 
@@ -507,7 +507,7 @@ approx_candidates(
        int rc;
        char *dbname;
        slap_mask_t mask;
-       struct berval prefix = {0};
+       struct berval prefix = {0, NULL};
        struct berval *keys = NULL;
        MatchingRule *mr;
 
@@ -742,7 +742,7 @@ substring_candidates(
        int rc;
        char *dbname;
        slap_mask_t mask;
-       struct berval prefix = {0};
+       struct berval prefix = {0, NULL};
        struct berval *keys = NULL;
        MatchingRule *mr;
 
index f6c0cf9b625c09fa3bb67b5fee19092855cefaf7..d879f568a6828e9acc088520ee32e71e7908f2b4 100644 (file)
@@ -1,7 +1,7 @@
 /* idl.c - ldap id list handling routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -259,6 +259,8 @@ idl_fetch(
        }
        free( (char *) tmp );
 
+       assert( ID_BLOCK_NIDS(idl) == nids );
+
 #ifdef LDBM_DEBUG_IDL
        idl_check(idl);
 #endif
index f5078c0051313dffcc2ff3e3940e31349b07cba6..8abb05195e80710907e5933299623f24c792106e 100644 (file)
@@ -1,7 +1,7 @@
 /* index.c - routines for dealing with attribute indexes */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -32,14 +32,14 @@ static slap_mask_t index_mask(
                return mask;
        }
 
-       /* If there is a language tag, did we ever index the base
+       /* If there is a tagging option, did we ever index the base
         * type? If so, check for mask, otherwise it's not there.
         */
-       if( slap_ad_is_lang( desc ) && desc != desc->ad_type->sat_ad ) {
-               /* has language tag */
+       if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) {
+               /* has tagging option */
                attr_mask( be->be_private, desc->ad_type->sat_ad, &mask );
 
-               if( mask && ( mask ^ SLAP_INDEX_NOLANG ) ) {
+               if( mask && ( mask ^ SLAP_INDEX_NOTAGS ) ) {
                        *atname = desc->ad_type->sat_cname;
                        *dbname = desc->ad_type->sat_cname.bv_val;
                        return mask;
@@ -230,7 +230,7 @@ static int indexer(
 static int index_at_values(
        Backend *be,
        AttributeType *type,
-       struct berval *lang,
+       struct berval *tags,
        BerVarray vals,
        ID id,
        int op )
@@ -240,7 +240,7 @@ static int index_at_values(
        if( type->sat_sup ) {
                /* recurse */
                (void) index_at_values( be,
-                       type->sat_sup, lang,
+                       type->sat_sup, tags,
                        vals, id, op );
        }
 
@@ -256,12 +256,12 @@ static int index_at_values(
                        mask );
        }
 
-       if( lang->bv_len ) {
+       if( tags->bv_len ) {
                AttributeDescription *desc;
 
                mask = 0;
 
-               desc = ad_find_lang(type, lang);
+               desc = ad_find_tags(type, tags);
                if( desc ) {
                        attr_mask( be->be_private, desc, &mask );
                }
@@ -284,7 +284,7 @@ int index_values(
        int op )
 {
        (void) index_at_values( be,
-               desc->ad_type, &desc->ad_lang,
+               desc->ad_type, &desc->ad_tags,
                vals, id, op );
 
        return LDAP_SUCCESS;
index e6c6e21cb77a7fc3034f8556e33d6c247fd4bb04..cc023e8e18ece2f72b9f1c04073b6dfd19f897bd 100644 (file)
@@ -1,7 +1,7 @@
 /* init.c - initialize ldbm backend */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -71,9 +71,7 @@ ldbm_back_initialize(
        bi->bi_acl_attribute = ldbm_back_attribute;
        bi->bi_chk_referrals = ldbm_back_referrals;
        bi->bi_operational = ldbm_back_operational;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
        bi->bi_has_subordinates = ldbm_back_hasSubordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
        /*
         * hooks for slap tools
index a34cc06e979d6ed07a4d41966dd468b2f294f327..7daf460d787ec9f24dbbd713c426528b15ab2aee 100644 (file)
@@ -1,7 +1,7 @@
 /* modify.c - ldbm backend modify routine */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -65,7 +65,7 @@ int ldbm_modify_internal(
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: add\n", 0, 0, 0);
 #endif
 
-                       rc = modify_add_values( e, mod, text, textbuf, textlen );
+                       rc = modify_add_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( BACK_LDBM, INFO, 
@@ -84,7 +84,7 @@ int ldbm_modify_internal(
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: delete\n", 0, 0, 0);
 #endif
 
-                       rc = modify_delete_values( e, mod, text, textbuf, textlen );
+                       rc = modify_delete_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        assert( rc != LDAP_TYPE_OR_VALUE_EXISTS );
                        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
@@ -104,7 +104,7 @@ int ldbm_modify_internal(
                        Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: replace\n", 0, 0, 0);
 #endif
 
-                       rc = modify_replace_values( e, mod, text, textbuf, textlen );
+                       rc = modify_replace_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        if( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( BACK_LDBM, INFO, 
@@ -129,7 +129,7 @@ int ldbm_modify_internal(
                         */
                        mod->sm_op = LDAP_MOD_ADD;
 
-                       rc = modify_add_values( e, mod, text, textbuf, textlen );
+                       rc = modify_add_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
                        if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
                                rc = LDAP_SUCCESS;
                        }
index acc69ca33c83c30abd2c4371e85d1d19597539c9..dfd531629d3cf260a24f5b1dc597e8a462f6d8e1 100644 (file)
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
 #ifndef _PROTO_BACK_LDBM
 #define _PROTO_BACK_LDBM
 
+#include <ldap_cdefs.h>
+
+#include "external.h"
+
+LDAP_BEGIN_DECL
+
+/*
+ * alias.c
+ */
+Entry *deref_internal_r LDAP_P((
+       Backend *be,
+       Entry *e,
+       struct berval *dn,
+       int *err,
+       Entry **matched,
+       const char **text ));
+
+#define deref_entry_r( be, e, err, matched, text ) \
+       deref_internal_r( be, e, NULL, err, matched, text )
+#define deref_dn_r( be, dn, err, matched, text ) \
+       deref_internal_r( be, NULL, dn, err, matched, text)
+
 /*
  * attr.c
  */
 
-void attr_masks( struct ldbminfo *li, char *type, int *indexmask,
- int *syntaxmask );
-void attr_index_config( struct ldbminfo *li, char *fname, int lineno,
- int argc, char **argv, int init );
+void attr_mask LDAP_P(( struct ldbminfo *li,
+       AttributeDescription *desc,
+       slap_mask_t *indexmask ));
+
+int attr_index_config LDAP_P(( struct ldbminfo *li,
+       const char *fname, int lineno,
+       int argc, char **argv ));
+void attr_index_destroy LDAP_P(( Avlnode *tree ));
 
 /*
  * cache.c
  */
 
-void cache_set_state( struct cache *cache, Entry *e, int state );
-void cache_return_entry( struct cache *cache, Entry *e );
-int cache_add_entry_lock( struct cache *cache, Entry *e, int state );
-Entry * cache_find_entry_dn( struct cache *cache, char *dn );
-Entry * cache_find_entry_id( struct cache *cache, ID id );
-int cache_delete_entry( struct cache *cache, Entry *e );
+int cache_add_entry_rw LDAP_P(( Cache *cache, Entry *e, int rw ));
+int cache_update_entry LDAP_P(( Cache *cache, Entry *e ));
+void cache_return_entry_rw LDAP_P(( Cache *cache, Entry *e, int rw ));
+#define cache_return_entry_r(c, e) cache_return_entry_rw((c), (e), 0)
+#define cache_return_entry_w(c, e) cache_return_entry_rw((c), (e), 1)
+void cache_entry_commit LDAP_P(( Entry *e ));
+
+ID cache_find_entry_ndn2id LDAP_P(( Backend *be, Cache *cache, struct berval *ndn ));
+Entry * cache_find_entry_id LDAP_P(( Cache *cache, ID id, int rw ));
+int cache_delete_entry LDAP_P(( Cache *cache, Entry *e ));
+void cache_release_all LDAP_P(( Cache *cache ));
 
 /*
  * dbcache.c
  */
 
-struct dbcache * ldbm_cache_open( Backend *be, char *name, char *suffix,
- int flags );
-void ldbm_cache_close( Backend *be, struct dbcache *db );
-void ldbm_cache_flush_all( Backend *be );
-Datum ldbm_cache_fetch( struct dbcache *db, Datum key );
-int ldbm_cache_store( struct dbcache *db, Datum key, Datum data, int flags );
-int ldbm_cache_delete( struct dbcache *db, Datum key );
+DBCache * ldbm_cache_open LDAP_P(( Backend *be,
+       const char *name, const char *suffix, int flags ));
+void ldbm_cache_close LDAP_P(( Backend *be, DBCache *db ));
+void ldbm_cache_really_close LDAP_P(( Backend *be, DBCache *db ));
+void ldbm_cache_flush_all LDAP_P(( Backend *be ));
+void ldbm_cache_sync LDAP_P(( Backend *be ));
+#if 0 /* replaced by macro */
+Datum ldbm_cache_fetch LDAP_P(( DBCache *db, Datum key ));
+#else /* 1 */
+#define ldbm_cache_fetch( db, key )    ldbm_fetch( (db)->dbc_db, (key) )
+#endif /* 1 */
+int ldbm_cache_store LDAP_P(( DBCache *db, Datum key, Datum data, int flags ));
+int ldbm_cache_delete LDAP_P(( DBCache *db, Datum key ));
+void *ldbm_cache_sync_daemon LDAP_P(( void *));
 
 /*
  * dn2id.c
  */
 
-int dn2id_add( Backend *be, char *dn, ID id );
-ID dn2id( Backend *be, char *dn );
-int dn2id_delete( Backend *be, char *dn );
-Entry * dn2entry( Backend *be, char *dn, char **matched );
+int dn2id_add LDAP_P(( Backend *be, struct berval *dn, ID id ));
+int dn2id LDAP_P(( Backend *be, struct berval *dn, ID *idp ));
+int dn2idl LDAP_P(( Backend *be, struct berval *dn, int prefix, ID_BLOCK **idlp ));
+int dn2id_delete LDAP_P(( Backend *be, struct berval *dn, ID id ));
+
+Entry * dn2entry_rw LDAP_P(( Backend *be, struct berval *dn, Entry **matched, int rw ));
+#define dn2entry_r(be, dn, m) dn2entry_rw((be), (dn), (m), 0)
+#define dn2entry_w(be, dn, m) dn2entry_rw((be), (dn), (m), 1)
+
+/*
+ * entry.c
+ */
+int ldbm_back_entry_release_rw LDAP_P(( Backend *be,
+       Connection *conn, Operation *op,
+       Entry *e, int rw ));
 
 /*
  * filterindex.c
  */
 
-IDList * filter_candidates( Backend *be, Filter *f );
+ID_BLOCK * filter_candidates LDAP_P(( Backend *be, Filter *f ));
 
 /*
  * id2children.c
  */
 
-int id2children_add( Backend *be, Entry *p, Entry *e );
-int has_children( Backend *be, Entry *p );
+int id2children_add LDAP_P(( Backend *be, Entry *p, Entry *e ));
+int id2children_remove LDAP_P(( Backend *be, Entry *p, Entry *e ));
+int has_children LDAP_P(( Backend *be, Entry *p ));
 
 /*
  * id2entry.c
  */
 
-int id2entry_add( Backend *be, Entry *e );
-int id2entry_delete( Backend *be, Entry *e );
-Entry * id2entry( Backend *be, ID id );
+int id2entry_add LDAP_P(( Backend *be, Entry *e ));
+int id2entry_delete LDAP_P(( Backend *be, Entry *e ));
+
+Entry * id2entry_rw LDAP_P(( Backend *be, ID id, int rw )); 
+#define id2entry_r(be, id)     id2entry_rw((be), (id), 0)
+#define id2entry_w(be, id)     id2entry_rw((be), (id), 1)
 
 /*
  * idl.c
  */
 
-IDList * idl_alloc( int nids );
-IDList * idl_allids( Backend *be );
-void idl_free( IDList *idl );
-IDList * idl_fetch( Backend *be, struct dbcache *db, Datum key );
-int idl_insert_key( Backend *be, struct dbcache *db, Datum key, ID id );
-int idl_insert( IDList **idl, ID id, int maxids );
-IDList * idl_intersection( Backend *be, IDList *a, IDList *b );
-IDList * idl_union( Backend *be, IDList *a, IDList *b );
-IDList * idl_notin( Backend *be, IDList *a, IDList *b );
-ID idl_firstid( IDList *idl );
-ID idl_nextid( IDList *idl, ID id );
+ID_BLOCK * idl_alloc LDAP_P(( unsigned int nids ));
+ID_BLOCK * idl_allids LDAP_P(( Backend *be ));
+void idl_free LDAP_P(( ID_BLOCK *idl ));
+ID_BLOCK * idl_fetch LDAP_P(( Backend *be, DBCache *db, Datum key ));
+int idl_insert_key LDAP_P(( Backend *be, DBCache *db, Datum key, ID id ));
+int idl_insert LDAP_P(( ID_BLOCK **idl, ID id, unsigned int maxids ));
+int idl_delete_key LDAP_P(( Backend *be, DBCache *db, Datum key, ID id ));
+ID_BLOCK * idl_intersection LDAP_P(( Backend *be, ID_BLOCK *a, ID_BLOCK *b ));
+ID_BLOCK * idl_union LDAP_P(( Backend *be, ID_BLOCK *a, ID_BLOCK *b ));
+ID_BLOCK * idl_notin LDAP_P(( Backend *be, ID_BLOCK *a, ID_BLOCK *b ));
+ID idl_firstid LDAP_P(( ID_BLOCK *idl, ID *cursor ));
+ID idl_nextid LDAP_P(( ID_BLOCK *idl, ID *cursor ));
 
 /*
  * index.c
  */
+extern int
+index_is_indexed LDAP_P((
+       Backend *be,
+       AttributeDescription *desc ));
+
+extern int
+index_param LDAP_P((
+       Backend *be,
+       AttributeDescription *desc,
+       int ftype,
+       char **dbname,
+       slap_mask_t *mask,
+       struct berval *prefix ));
+
+extern int
+index_values LDAP_P((
+       Backend *be,
+       AttributeDescription *desc,
+       BerVarray vals,
+       ID id,
+       int op ));
+
+int index_entry LDAP_P(( Backend *be, int r, Entry *e, Attribute *ap ));
+#define index_entry_add(be,e,ap) index_entry((be),SLAP_INDEX_ADD_OP,(e),(ap))
+#define index_entry_del(be,e,ap) index_entry((be),SLAP_INDEX_DELETE_OP,(e),(ap))
 
-int index_add_entry( Backend *be, Entry *e );
-int index_add_mods( Backend *be, LDAPMod *mods, ID id );
-IDList * index_read( Backend *be, char *type, int indextype, char *val );
-int index_add_values( Backend *be, char *type, struct berval **vals, ID  id );
 
 /*
- * kerberos.c
+ * key.c
  */
+extern int
+key_change LDAP_P((
+    Backend            *be,
+    DBCache    *db,
+    struct berval *k,
+    ID                 id,
+    int                        op ));
+extern int
+key_read LDAP_P((
+    Backend    *be,
+       DBCache *db,
+    struct berval *k,
+       ID_BLOCK **idout ));
 
-#ifdef KERBEROS
-/* krbv4_ldap_auth( Backend *be, struct berval *cred, AUTH_DAT *ad ); */
-#endif
+/*
+ * passwd.c
+ */
+extern BI_op_extended ldbm_back_exop_passwd;
+
+/*
+ * modify.c
+ * These prototypes are placed here because they are used by modify and
+ * modify rdn which are implemented in different files. 
+ *
+ * We need ldbm_internal_modify here because of LDAP modrdn & modify use 
+ * it. If we do not add this, there would be a bunch of code replication 
+ * here and there and of course the likelihood of bugs increases.
+ * Juan C. Gomez (gomez@engr.sgi.com) 05/18/99
+ * 
+ */
+
+/* returns LDAP error code indicating error OR SLAPD_ABANDON */
+int ldbm_modify_internal LDAP_P((Backend *be,
+       Connection *conn, Operation *op,
+       const char *dn, Modifications *mods, Entry *e,
+       const char **text, char *textbuf, size_t textlen ));
 
 /*
  * nextid.c
  */
 
-ID next_id( Backend *be );
-void next_id_return( Backend *be, ID id );
-ID next_id_get( Backend *be );
+int next_id LDAP_P(( Backend *be, ID *idp ));
+int next_id_get LDAP_P(( Backend *be, ID *idp ));
+int next_id_write LDAP_P(( Backend *be, ID id ));
 
+LDAP_END_DECL
 #endif
index 6408654e9dfe735a825aed8f2016f11ea2a43b9f..61ce46deedd859847023f76e099af72056e933fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
@@ -154,8 +154,8 @@ meta_back_add(
                }
 
                ldap_back_map( &li->targets[ candidate ]->at_map,
-                               &a->a_desc->ad_cname, &mapped, 0);
-               if ( mapped.bv_val == NULL ) {
+                               &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
+               if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
                        continue;
                }
 
diff --git a/servers/slapd/back-meta/attribute.c b/servers/slapd/back-meta/attribute.c
new file mode 100644 (file)
index 0000000..679f65e
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ *
+ * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
+ *
+ * This work has been developed to fulfill the requirements
+ * of SysNet s.n.c. <http:www.sys-net.it> and it has been donated
+ * to the OpenLDAP Foundation in the hope that it may be useful
+ * to the Open Source community, but WITHOUT ANY WARRANTY.
+ *
+ * Permission is granted to anyone to use this software for any purpose
+ * on any computer system, and to alter it and redistribute it, subject
+ * to the following restrictions:
+ * 
+ * 1. The author and SysNet s.n.c. are not responsible for the consequences
+ *    of use of this software, no matter how awful, even if they arise from 
+ *    flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ *    explicit claim or by omission.  Since few users ever read sources,
+ *    credits should appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.  Since few users
+ *    ever read sources, credits should appear in the documentation.
+ *    SysNet s.n.c. cannot be responsible for the consequences of the
+ *    alterations.
+ *
+ * 4. This notice may not be removed or altered.
+ * 
+ * 
+ * This software is based on the backend back-ldap, implemented
+ * by Howard Chu <hyc@highlandsun.com>, and modified by Mark Valence
+ * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
+ * contributors. The contribution of the original software to the present
+ * implementation is acknowledged in this copyright statement.
+ * 
+ * A special acknowledgement goes to Howard for the overall architecture
+ * (and for borrowing large pieces of code), and to Mark, who implemented
+ * from scratch the attribute/objectclass mapping.
+ * 
+ * The original copyright statement follows.
+ *
+ * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
+ *
+ * Permission is granted to anyone to use this software for any purpose
+ * on any computer system, and to alter it and redistribute it, subject
+ * to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ *    software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ *    explicit claim or by omission.  Since few users ever read sources,
+ *    credits should appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.  Since few users
+ *    ever read sources, credits should appear in the
+ *    documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ *
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "../back-ldap/back-ldap.h"
+#include "back-meta.h"
+
+
+/* return 0 IFF we can retrieve the attributes
+ * of entry with e_ndn
+ */
+
+/*
+ * FIXME: I never testd this function; I know it compiles ... :)
+ */
+int
+meta_back_attribute(
+               Backend                 *be,
+               Connection              *conn,
+               Operation               *op,
+               Entry                   *target,
+               struct berval           *ndn,
+               AttributeDescription    *entry_at,
+               BerVarray                       *vals
+)
+{
+       struct metainfo *li = ( struct metainfo * )be->be_private;    
+       int rc = 1, i, j, count, is_oc, candidate;
+       Attribute *attr;
+       BerVarray abv, v;
+       char **vs; 
+       struct berval   mapped;
+       LDAPMessage     *result, *e;
+       char *gattr[ 2 ];
+       LDAP *ld;
+
+       *vals = NULL;
+       if ( target != NULL && dn_match( &target->e_nname, ndn ) ) {
+               /* we already have a copy of the entry */
+               /* attribute and objectclass mapping has already been done */
+               attr = attr_find( target->e_attrs, entry_at );
+               if ( attr == NULL ) {
+                       return 1;
+               }
+
+               for ( count = 0; attr->a_vals[ count ].bv_val != NULL; count++ )
+                       ;
+               v = ( BerVarray )ch_calloc( ( count + 1 ), sizeof( struct berval ) );
+               if ( v == NULL ) {
+                       return 1;
+               }
+
+               for ( j = 0, abv = attr->a_vals; --count >= 0; abv++ ) {
+                       if ( abv->bv_len > 0 ) {
+                               ber_dupbv( &v[ j ], abv );
+                               if ( v[ j ].bv_val == NULL ) {
+                                       break;
+                               }
+                       }
+               }
+               v[ j ].bv_val = NULL;
+               *vals = v;
+
+               return 0;
+       } /* else */
+
+       candidate = meta_back_select_unique_candidate( li, ndn );
+       if ( candidate == -1 ) {
+               return 1;
+       }
+
+       ldap_back_map( &li->targets[ candidate ]->at_map,
+                       &entry_at->ad_cname, &mapped, BACKLDAP_MAP );
+       if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' )
+               return 1;
+
+       rc =  ldap_initialize( &ld, li->targets[ candidate ]->uri );
+       if ( rc != LDAP_SUCCESS ) {
+               return 1;
+       }
+
+       rc = ldap_bind_s( ld, li->targets[ candidate ]->binddn.bv_val,
+                       li->targets[ candidate ]->bindpw.bv_val, LDAP_AUTH_SIMPLE );
+       if ( rc != LDAP_SUCCESS) {
+               return 1;
+       }
+
+       gattr[ 0 ] = mapped.bv_val;
+       gattr[ 1 ] = NULL;
+       if ( ldap_search_ext_s( ld, ndn->bv_val, LDAP_SCOPE_BASE, 
+                               "(objectClass=*)",
+                               gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
+                               LDAP_NO_LIMIT, &result) == LDAP_SUCCESS) {
+               if ( ( e = ldap_first_entry( ld, result ) ) != NULL ) {
+                       vs = ldap_get_values( ld, e, mapped.bv_val );
+                       if ( vs != NULL ) {
+                               for ( count = 0; vs[ count ] != NULL;
+                                               count++ ) { }
+                               v = ( BerVarray )ch_calloc( ( count + 1 ),
+                                               sizeof( struct berval ) );
+                               if ( v == NULL ) {
+                                       ldap_value_free( vs );
+                               } else {
+                                       is_oc = ( strcasecmp( "objectclass", mapped.bv_val ) == 0 );
+                                       for ( i = 0, j = 0; i < count; i++ ) {
+                                               ber_str2bv( vs[ i ], 0, 0, &v[ j ] );
+                                               if ( !is_oc ) {
+                                                       if ( v[ j ].bv_val == NULL ) {
+                                                               ch_free( vs[ i ] );
+                                                       } else {
+                                                               j++;
+                                                       }
+                                               } else {
+                                                       ldap_back_map( &li->targets[ candidate ]->oc_map, &v[ j ], &mapped, BACKLDAP_REMAP );
+                                                       if ( mapped.bv_val && mapped.bv_val[0] != '\0' ) {
+                                                               ber_dupbv( &v[ j ], &mapped );
+                                                               if ( v[ j ].bv_val ) {
+                                                                       j++;
+                                                               }
+                                                       }
+                                                       ch_free( vs[ i ] );
+                                               }
+                                       }
+                                       v[ j ].bv_val = NULL;
+                                       *vals = v;
+                                       rc = 0;
+                                       ch_free( vs );
+                               }
+                       }
+               }
+               ldap_msgfree( result );
+       }
+       ldap_unbind( ld );
+
+       return(rc);
+}
+
index f14345a208268af751a6fb7b54f03a648f654aca..6b02654da006c532ae1063cea8be924a063a272c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
@@ -91,6 +91,7 @@ struct metasingleconn {
        
        LDAP                    *ld;
        struct berval           bound_dn;
+       struct berval           cred;
        int                     bound;
 #define META_UNBOUND           0
 #define META_BOUND             1
@@ -149,6 +150,8 @@ struct metainfo {
        
        ldap_pvt_thread_mutex_t conn_mutex;
        Avlnode                 *conntree;
+
+       int                     savecred;
 };
 
 #define META_OP_ALLOW_MULTIPLE         0x00
index 2a800c5c5c1728c445c48bf48902d70fbe23b2c5..272ecb901a11133392ffea90d19c5dd441e00fe4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
@@ -77,6 +77,8 @@
 #include "../back-ldap/back-ldap.h"
 #include "back-meta.h"
 
+static LDAP_REBIND_PROC        meta_back_rebind;
+
 static int
 meta_back_do_single_bind(
                struct metainfo         *li,
@@ -293,6 +295,15 @@ meta_back_do_single_bind(
                lc->conns[ candidate ].bound = META_BOUND;
                lc->bound_target = candidate;
 
+               if ( li->savecred ) {
+                       if ( lc->conns[ candidate ].cred.bv_val )
+                               ch_free( lc->conns[ candidate ].cred.bv_val );
+                       ber_dupbv( &lc->conns[ candidate ].cred, cred );
+                       ldap_set_rebind_proc( lc->conns[ candidate ].ld, 
+                                       meta_back_rebind, 
+                                       &lc->conns[ candidate ] );
+               }
+
                if ( li->cache.ttl != META_DNCACHE_DISABLED
                                && ndn->bv_len != 0 ) {
                        ( void )meta_dncache_update_entry( &li->cache,
@@ -428,6 +439,21 @@ meta_back_is_valid( struct metaconn *lc, int candidate )
        return 0;
 }
 
+/*
+ * meta_back_rebind
+ *
+ * This is a callback used for chasing referrals using the same
+ * credentials as the original user on this session.
+ */
+static int 
+meta_back_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
+       ber_int_t msgid, void *params )
+{
+       struct metasingleconn *lc = params;
+
+       return ldap_bind_s( ld, lc->bound_dn.bv_val, lc->cred.bv_val, LDAP_AUTH_SIMPLE );
+}
+
 /*
  * FIXME: error return must be handled in a cleaner way ...
  */
index 75a4c868e4e3cf7bc4ba6d360ef638069c625050..815e515cadd6633271948233b9429a8cf340ef15 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
@@ -113,6 +113,7 @@ meta_back_compare(
                struct berval mapped_value = ava->aa_value;
 
                if ( lsc->candidate != META_CANDIDATE ) {
+                       msgid[ i ] = -1;
                        continue;
                }
 
@@ -152,13 +153,12 @@ meta_back_compare(
                /*
                 * if attr is objectClass, try to remap the value
                 */
-               if ( ava->aa_desc->ad_type->sat_oid 
-                       == slap_schema.si_ad_objectClass->ad_type->sat_oid ) {
+               if ( ava->aa_desc == slap_schema.si_ad_objectClass ) {
                        ldap_back_map( &li->targets[ i ]->oc_map,
-                                       &ava->aa_value, &mapped_value, 0 );
+                                       &ava->aa_value, &mapped_value,
+                                       BACKLDAP_MAP );
 
-                       if ( mapped_value.bv_val == NULL ) {
-                               lsc->candidate = META_NOT_CANDIDATE;
+                       if ( mapped_value.bv_val == NULL || mapped_value.bv_val[0] == '\0' ) {
                                continue;
                        }
                /*
@@ -166,9 +166,9 @@ meta_back_compare(
                 */
                } else {
                        ldap_back_map( &li->targets[ i ]->at_map,
-                               &ava->aa_desc->ad_cname, &mapped_attr, 0 );
-                       if ( mapped_attr.bv_val == NULL ) {
-                               lsc->candidate = META_NOT_CANDIDATE;
+                               &ava->aa_desc->ad_cname, &mapped_attr,
+                               BACKLDAP_MAP );
+                       if ( mapped_attr.bv_val == NULL || mapped_attr.bv_val[0] == '\0' ) {
                                continue;
                        }
                }
@@ -180,11 +180,6 @@ meta_back_compare(
                 */
                msgid[ i ] = ldap_compare( lc->conns[ i ].ld, mdn,
                                mapped_attr.bv_val, mapped_value.bv_val );
-               if ( msgid[ i ] == -1 ) {
-                       lsc->candidate = META_NOT_CANDIDATE;
-                       continue;
-               }
-
                if ( mdn != dn->bv_val ) {
                        free( mdn );
                }
@@ -195,6 +190,10 @@ meta_back_compare(
                        free( mapped_value.bv_val );
                }
 
+               if ( msgid[ i ] == -1 ) {
+                       continue;
+               }
+
                ++candidates;
        }
 
@@ -210,7 +209,7 @@ meta_back_compare(
                        int lrc;
                        LDAPMessage *res = NULL;
 
-                       if ( lsc->candidate != META_CANDIDATE ) {
+                       if ( msgid[ i ] == -1 ) {
                                continue;
                        }
 
@@ -267,10 +266,11 @@ meta_back_compare(
                                        last = i;
                                        break;
                                }
-                               lsc->candidate = META_NOT_CANDIDATE;
+                               msgid[ i ] = -1;
                                --candidates;
+
                        } else {
-                               lsc->candidate = META_NOT_CANDIDATE;
+                               msgid[ i ] = -1;
                                --candidates;
                                if ( res ) {
                                        ldap_msgfree( res );
index 107ac5cadb9cc1c350fd99aa8f8527c8ec90e573..e02adc8df63d0ed9df7c672e5ba1605bd109a03c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
@@ -73,6 +73,7 @@
 
 #include "slap.h"
 #include "../back-ldap/back-ldap.h"
+#include "../../../libraries/libldap/ldap-int.h"
 #include "back-meta.h"
 
 static struct metatarget *
@@ -121,8 +122,7 @@ meta_back_db_config(
 #if 0
                int             j;
 #endif /* uncomment if uri MUST be a branch of suffix */
-               LDAPURLDesc     *ludp;
-               char            *last;
+               LDAPURLDesc     *ludp, *tmpludp;
                struct berval   dn;
                int             rc;
                
@@ -157,7 +157,7 @@ meta_back_db_config(
                /*
                 * uri MUST be legal!
                 */
-               if ( ldap_url_parse( argv[ 1 ], &ludp ) != LDAP_SUCCESS ) {
+               if ( ldap_url_parselist_ext( &ludp, argv[ 1 ], "\t" ) != LDAP_SUCCESS ) {
                        fprintf( stderr,
        "%s: line %d: unable to parse URI"
        " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
@@ -191,10 +191,25 @@ meta_back_db_config(
                        return( 1 );
                }
 
-               li->targets[ i ]->uri = ch_strdup( argv[ 1 ] );
-               last = strstr( li->targets[ i ]->uri, ludp->lud_dn );
-               assert( last != NULL );
-               last[ 0 ] = '\0';
+               ludp->lud_dn[ 0 ] = '\0';
+
+               for ( tmpludp = ludp->lud_next; tmpludp; tmpludp = tmpludp->lud_next ) {
+                       if ( tmpludp->lud_dn != NULL && tmpludp->lud_dn[ 0 ] != '\0' ) {
+                               fprintf( stderr, "%s: line %d: "
+                                               "multiple URIs must have no DN part\n",
+                                       fname, lineno, argv[ 1 ] );
+                               return( 1 );
+
+                       }
+               }
+
+               li->targets[ i ]->uri = ldap_url_list2urls( ludp );
+               ldap_free_urllist( ludp );
+               if ( li->targets[ i ]->uri == NULL) {
+                       fprintf( stderr, "%s: line %d: no memory?\n",
+                                       fname, lineno );
+                       return( 1 );
+               }
                
                /*
                 * uri MUST be a branch of suffix!
@@ -238,8 +253,6 @@ meta_back_db_config(
                        }
                }
 #endif
-               
-               ldap_free_urldesc( ludp );
 
 #if 0
                fprintf(stderr, "%s: line %d: URI \"%s\", suffix \"%s\"\n",
@@ -343,6 +356,16 @@ meta_back_db_config(
                }
                ber_str2bv( argv[ 1 ], 0L, 1, &li->targets[ i ]->bindpw );
                
+       /* save bind creds for referral rebinds? */
+       } else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) {
+               if (argc != 1) {
+                       fprintf( stderr,
+       "%s: line %d: rebind-as-user takes no arguments\n",
+                           fname, lineno );
+                       return( 1 );
+               }
+               li->savecred = 1;
+       
        /* name to use as pseudo-root dn */
        } else if ( strcasecmp( argv[ 0 ], "pseudorootdn" ) == 0 ) {
                int             i = li->ntargets-1;
index e9deeb00512356b457c86febf5c2523811aba765..8289819a88ec55313a208228b866e94aa91aa91e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
@@ -224,11 +224,10 @@ init_one_conn(
                Connection *conn, 
                Operation *op, 
                struct metatarget *lt, 
-               int vers,
                struct metasingleconn *lsc
                )
 {
-       int err;
+       int err, vers;
 
        /*
         * Already init'ed
@@ -244,11 +243,12 @@ init_one_conn(
        if ( err != LDAP_SUCCESS ) {
                return ldap_back_map_result( err );
        }
-       
+
        /*
         * Set LDAP version. This will always succeed: If the client
         * bound with a particular version, then so can we.
         */
+       vers = conn->c_protocol;
        ldap_set_option( lsc->ld, LDAP_OPT_PROTOCOL_VERSION, &vers );
 
        /*
@@ -335,7 +335,7 @@ meta_back_getconn(
                int             *candidate )
 {
        struct metaconn *lc, lc_curr;
-       int vers, cached = -1, i = -1, err = LDAP_SUCCESS;
+       int cached = -1, i = -1, err = LDAP_SUCCESS;
        int new_conn = 0;
 
        /* Searches for a metaconn in the avl tree */
@@ -352,8 +352,6 @@ meta_back_getconn(
                new_conn = 1;
        }
 
-       vers = conn->c_protocol;
-
        /*
         * looks in cache, if any
         */
@@ -406,7 +404,7 @@ meta_back_getconn(
                 * sends the appropriate result.
                 */
                err = init_one_conn( conn, op, li->targets[ i ],
-                               vers, &lc->conns[ i ] );
+                               &lc->conns[ i ] );
                if ( err != LDAP_SUCCESS ) {
                
                        /*
@@ -436,7 +434,7 @@ meta_back_getconn(
                         * also init'd
                         */
                        int lerr = init_one_conn( conn, op, li->targets[ i ],
-                                       vers, &lc->conns[ i ] );
+                                       &lc->conns[ i ] );
                        if ( lerr != LDAP_SUCCESS ) {
                                
                                /*
@@ -464,7 +462,7 @@ meta_back_getconn(
                                 */
                                int lerr = init_one_conn( conn, op,
                                                li->targets[ i ],
-                                               vers, &lc->conns[ i ] );
+                                               &lc->conns[ i ] );
                                if ( lerr != LDAP_SUCCESS ) {
                                
                                        /*
index 70a6366cebb6ba13468423358fffcbddbbe00488..632a72448938d7e3dce450bca568a9ca520bea2f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
@@ -222,13 +222,13 @@ meta_back_group(
        }
        
        ldap_back_map( &li->targets[ candidate ]->oc_map,
-                       &group_oc_name, &group_oc_name, 0 );
-       if ( group_oc_name.bv_val == NULL ) {
+                       &group_oc_name, &group_oc_name, BACKLDAP_MAP );
+       if ( group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0' ) {
                goto cleanup;
        }
        ldap_back_map( &li->targets[ candidate ]->at_map,
-                       &group_at_name, &group_at_name, 0 );
-       if ( group_at_name.bv_val == NULL ) {
+                       &group_at_name, &group_at_name, BACKLDAP_MAP );
+       if ( group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0' ) {
                goto cleanup;
        }
 
index eae98ba6aa90842217fceda899fca19004af8ce2..5d3f2b8f20afcea0ba7062b4aca4735240721232 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
@@ -157,9 +157,10 @@ meta_back_db_init(
 
 static void
 conn_free( 
-       struct metaconn *lc
+       void *v_lc
 )
 {
+       struct metaconn *lc = v_lc;
        struct metasingleconn *lsc;
 
        for ( lsc = lc->conns; !META_LAST(lsc); lsc++ ) {
@@ -205,9 +206,9 @@ target_free(
                rewrite_info_delete( lt->rwinfo );
        }
        avl_free( lt->oc_map.remap, NULL );
-       avl_free( lt->oc_map.map, ( AVL_FREE )mapping_free );
+       avl_free( lt->oc_map.map, mapping_free );
        avl_free( lt->at_map.remap, NULL );
-       avl_free( lt->at_map.map, ( AVL_FREE )mapping_free );
+       avl_free( lt->at_map.map, mapping_free );
 }
 
 int
@@ -228,8 +229,7 @@ meta_back_db_destroy(
                ldap_pvt_thread_mutex_lock( &li->conn_mutex );
 
                if ( li->conntree ) {
-                       avl_free( li->conntree,
-                                       ( AVL_FREE )conn_free );
+                       avl_free( li->conntree, conn_free );
                }
 
                /*
@@ -245,8 +245,7 @@ meta_back_db_destroy(
 
                ldap_pvt_thread_mutex_lock( &li->cache.mutex );
                if ( li->cache.tree ) {
-                       avl_free( li->cache.tree,
-                                       ( AVL_FREE )meta_dncache_free );
+                       avl_free( li->cache.tree, meta_dncache_free );
                }
                
                ldap_pvt_thread_mutex_unlock( &li->cache.mutex );
index 57dc40f90b0b6c743d6c8e8d5911b21be83b3804..01fec49787949fe77839ed497f18c52dcd08cc12 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
@@ -158,8 +158,9 @@ meta_back_modify(
                }
 
                ldap_back_map( &li->targets[ candidate ]->at_map,
-                               &ml->sml_desc->ad_cname, &mapped, 0 );
-               if ( mapped.bv_val == NULL ) {
+                               &ml->sml_desc->ad_cname, &mapped,
+                               BACKLDAP_MAP );
+               if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
                        continue;
                }
 
index 0a2e04a07fb3d1dc36831fefd2b7cea9040ea40a..1243ba0f288e21d7775ef67efeb029e34bd75f88 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  *
  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
@@ -213,6 +213,7 @@ meta_back_search(
                char    *mapped_filter, **mapped_attrs;
                
                if ( lsc->candidate != META_CANDIDATE ) {
+                       msgid[ i ] = -1;
                        continue;
                }
 
@@ -250,7 +251,7 @@ meta_back_search(
                                        /*
                                         * this target is no longer candidate
                                         */
-                                       lsc->candidate = META_NOT_CANDIDATE;
+                                       msgid[ i ] = -1;
                                        continue;
                                }
                                break;
@@ -273,7 +274,7 @@ meta_back_search(
                                /*
                                 * this target is no longer candidate
                                 */
-                               lsc->candidate = META_NOT_CANDIDATE;
+                               msgid[ i ] = -1;
                                continue;
                        }
 
@@ -356,7 +357,8 @@ meta_back_search(
                 * Maps attributes in filter
                 */
                mapped_filter = ldap_back_map_filter( &li->targets[ i ]->at_map,
-                               &li->targets[ i ]->oc_map, &mfilter, 0 );
+                               &li->targets[ i ]->oc_map, &mfilter,
+                               BACKLDAP_MAP );
                if ( mapped_filter == NULL ) {
                        mapped_filter = ( char * )mfilter.bv_val;
                } else {
@@ -371,7 +373,7 @@ meta_back_search(
                 * Maps required attributes
                 */
                mapped_attrs = ldap_back_map_attrs( &li->targets[ i ]->at_map,
-                               attrs, 0 );
+                               attrs, BACKLDAP_MAP );
                if ( mapped_attrs == NULL && attrs) {
                        for ( count=0; attrs[ count ].an_name.bv_val; count++ );
                        mapped_attrs = ch_malloc( ( count + 1 ) * sizeof(char *));
@@ -386,11 +388,6 @@ meta_back_search(
                 */
                msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
                                mapped_filter, mapped_attrs, attrsonly ); 
-               if ( msgid[ i ] == -1 ) {
-                       lsc->candidate = META_NOT_CANDIDATE;
-                       continue;
-               }
-
                if ( mapped_attrs ) {
                        free( mapped_attrs );
                        mapped_attrs = NULL;
@@ -404,6 +401,10 @@ meta_back_search(
                        mbase = NULL;
                }
 
+               if ( msgid[ i ] == -1 ) {
+                       continue;
+               }
+
                ++candidates;
        }
 
@@ -426,7 +427,7 @@ meta_back_search(
                ab = op->o_abandon;
 
                for ( i = 0, lsc = lc->conns; !META_LAST(lsc); lsc++, i++ ) {
-                       if ( lsc->candidate != META_CANDIDATE ) {
+                       if ( msgid[ i ] == -1 ) {
                                continue;
                        }
                        
@@ -557,7 +558,7 @@ meta_back_search(
                                 * When no candidates are left,
                                 * the outer cycle finishes
                                 */
-                               lsc->candidate = META_NOT_CANDIDATE;
+                               msgid[ i ] = -1;
                                --candidates;
                        }
                }
@@ -726,8 +727,8 @@ meta_send_entry(
 
        while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
                ldap_back_map( &li->targets[ target ]->at_map, 
-                               &a, &mapped, 1 );
-               if ( mapped.bv_val == NULL ) {
+                               &a, &mapped, BACKLDAP_REMAP );
+               if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
                        continue;
                }
                attr = ( Attribute * )ch_malloc( sizeof( Attribute ) );
@@ -770,8 +771,8 @@ meta_send_entry(
                        for ( last = 0; attr->a_vals[ last ].bv_val; ++last );
                        for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
                                ldap_back_map( &li->targets[ target]->oc_map,
-                                               bv, &mapped, 1 );
-                               if ( mapped.bv_val == NULL ) {
+                                               bv, &mapped, BACKLDAP_REMAP );
+                               if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
                                        free( bv->bv_val );
                                        bv->bv_val = NULL;
                                        if ( --last < 0 ) {
index 96439a715d97c8da3c02f5dc074e4e38be6bdd83..6217b12733beff4b3294787e4b589a567d88ec55 100644 (file)
@@ -1,6 +1,6 @@
 /* database.c - deals with database subsystem */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -76,6 +76,17 @@ monitor_subsys_database_init(
        }
 
        if ( slap_str2ad( "seeAlso", &ad_seeAlso, &text ) != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, CRIT,
+                       "monitor_subsys_database_init: "
+                       "unable to find 'seeAlso' attribute description\n",
+                       0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "monitor_subsys_database_init: "
+                       "unable to find 'seeAlso' attribute description\n",
+                       0, 0, 0 );
+#endif
                return( -1 );
        }
 
diff --git a/servers/slapd/back-perl/README b/servers/slapd/back-perl/README
new file mode 100644 (file)
index 0000000..302cb82
--- /dev/null
@@ -0,0 +1,25 @@
+
+Differences from 2.0 Perl API:
+
+- Perl 5.6 is supported
+
+- backend methods return actual LDAP result codes, not
+  true/false; this gives the Perl module finer control
+  of the error returned to the client
+
+- a filterSearchResults configuration file directive was
+  added to tell the backend glue that the results returned
+  from the Perl module are candidates only
+
+- the "init" method is called after the backend has been
+  initialized - this lets you do some initialization after
+  *all* configuration file directives have been read
+
+- the interface for the search method is improved to
+  pass the scope, deferencing policy, size limit, etc.
+  See SampleLDAP.pm for details.
+
+These changes were sponsored by myinternet Limited.
+
+Luke Howard <lukeh@padl.com>
+
index ccc4f1391e35d3c7506457e144d203435815d26b..25bef986fbb7722754f504522f4dad0fa8f8b873 100644 (file)
@@ -263,9 +263,11 @@ backsql_has_children(
        return rc;
 }
 
-int
-backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
+static int
+backsql_get_attr_vals( void *v_at, void *v_bsi )
 {
+       backsql_at_map_rec *at  = v_at;
+       backsql_srch_info  *bsi = v_bsi;
        RETCODE         rc;
        SQLHSTMT        sth;
        BACKSQL_ROW_NTS row;
@@ -403,7 +405,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
        } else {
                Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
                        "retrieving all attributes\n", 0, 0, 0 );
-               avl_apply( bsi->oc->attrs, (AVL_APPLY)backsql_get_attr_vals,
+               avl_apply( bsi->oc->attrs, backsql_get_attr_vals,
                                bsi, 0, AVL_INORDER );
        }
 
index c78620445fae533d66c6fe37b99678619729fb3e..6244955033b07ae2c8fff893139481c4c54277c2 100644 (file)
  * Uses the pointer to the ObjectClass structure
  */
 static int
-backsql_cmp_oc( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
+backsql_cmp_oc( const void *v_m1, const void *v_m2 )
 {
+       const backsql_oc_map_rec *m1 = v_m1, *m2 = v_m2;
        return ( m1->oc < m2->oc ? -1 : ( m1->oc > m2->oc ? 1 : 0 ) );
 }
 
 static int
-backsql_cmp_oc_id( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
+backsql_cmp_oc_id( const void *v_m1, const void *v_m2 )
 {
+       const backsql_oc_map_rec *m1 = v_m1, *m2 = v_m2;
        return ( m1->id < m2->id ? -1 : ( m1->id > m2->id ? 1 : 0 ) );
 }
 
@@ -41,8 +43,9 @@ backsql_cmp_oc_id( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
  * Uses the pointer to the AttributeDescription structure
  */
 static int
-backsql_cmp_attr( backsql_at_map_rec *m1, backsql_at_map_rec *m2 )
+backsql_cmp_attr( const void *v_m1, const void *v_m2 )
 {
+       const backsql_at_map_rec *m1 = v_m1, *m2 = v_m2;
        return ( m1->ad < m2->ad ? -1 : ( m1->ad > m2->ad ? 1 : 0 ) );
 }
 
@@ -116,8 +119,7 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
        at_map->param_order = 0;
        at_map->expect_return = 0;
        backsql_make_attr_query( oc_map, at_map );
-       avl_insert( &oc_map->attrs, at_map, 
-                       (AVL_CMP)backsql_cmp_attr, NULL );
+       avl_insert( &oc_map->attrs, at_map, backsql_cmp_attr, NULL );
 
        at_map = (backsql_at_map_rec *)ch_calloc( 1, 
                        sizeof( backsql_at_map_rec ) );
@@ -145,8 +147,7 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
        at_map->param_order = 0;
        at_map->expect_return = 0;
        backsql_make_attr_query( oc_map, at_map );
-       avl_insert( &oc_map->attrs, at_map, 
-                       (AVL_CMP)backsql_cmp_attr, NULL );
+       avl_insert( &oc_map->attrs, at_map, backsql_cmp_attr, NULL );
 
        return 1;
 }
@@ -259,10 +260,8 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
                 */
 
                oc_map->attrs = NULL;
-               avl_insert( &si->oc_by_oc, oc_map,
-                               (AVL_CMP)backsql_cmp_oc, NULL );
-               avl_insert( &si->oc_by_id, oc_map,
-                               (AVL_CMP)backsql_cmp_oc_id, NULL );
+               avl_insert( &si->oc_by_oc, oc_map, backsql_cmp_oc, NULL );
+               avl_insert( &si->oc_by_id, oc_map, backsql_cmp_oc_id, NULL );
                oc_id = oc_map->id;
                Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
                        "objectClass '%s': keytbl='%s' keycol='%s'\n",
@@ -367,8 +366,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
                        Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
                                "preconstructed query '%s'\n",
                                at_map->query, 0, 0 );
-                       avl_insert( &oc_map->attrs, at_map, 
-                                       (AVL_CMP)backsql_cmp_attr, NULL );
+                       avl_insert( &oc_map->attrs, at_map, backsql_cmp_attr, NULL );
                }
                backsql_FreeRow( &at_row );
                SQLFreeStmt( at_sth, SQL_CLOSE );
@@ -393,8 +391,7 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc )
 #endif /* BACKSQL_TRACE */
 
        tmp.oc = oc;
-       res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp,
-                       (AVL_CMP)backsql_cmp_oc );
+       res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp, backsql_cmp_oc );
 #ifdef BACKSQL_TRACE
        if ( res != NULL ) {
                Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
@@ -425,8 +422,7 @@ backsql_name2oc( backsql_info *si, struct berval *oc_name )
                return NULL;
        }
 
-       res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp,
-                       (AVL_CMP)backsql_cmp_oc );
+       res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp, backsql_cmp_oc );
 #ifdef BACKSQL_TRACE
        if ( res != NULL ) {
                Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
@@ -453,7 +449,7 @@ backsql_id2oc( backsql_info *si, unsigned long id )
 
        tmp.id = id;
        res = (backsql_oc_map_rec *)avl_find( si->oc_by_id, &tmp,
-                       (AVL_CMP)backsql_cmp_oc_id );
+                       backsql_cmp_oc_id );
 
 #ifdef BACKSQL_TRACE
        if ( res != NULL ) {
@@ -482,7 +478,7 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
 
        tmp.ad = ad;
        res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
-                       (AVL_CMP)backsql_cmp_attr );
+                       backsql_cmp_attr );
 
 #ifdef BACKSQL_TRACE
        if ( res != NULL ) {
@@ -518,7 +514,7 @@ backsql_name2at( backsql_oc_map_rec* objclass, struct berval *attr )
        }
 
        res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
-                       (AVL_CMP)backsql_cmp_attr );
+                       backsql_cmp_attr );
 
 #ifdef BACKSQL_TRACE
        if ( res != NULL ) {
@@ -535,8 +531,9 @@ backsql_name2at( backsql_oc_map_rec* objclass, struct berval *attr )
 }
 
 static void
-backsql_free_attr( backsql_at_map_rec *at )
+backsql_free_attr( void *v_at )
 {
+       backsql_at_map_rec *at = v_at;
        Debug( LDAP_DEBUG_TRACE, "==>free_attr(): '%s'\n", 
                        at->ad->ad_cname.bv_val, 0, 0 );
        ch_free( at->sel_expr.bv_val );
@@ -567,11 +564,12 @@ backsql_free_attr( backsql_at_map_rec *at )
 }
 
 static void
-backsql_free_oc( backsql_oc_map_rec *oc )
+backsql_free_oc( void *v_oc )
 {
+       backsql_oc_map_rec *oc = v_oc;
        Debug( LDAP_DEBUG_TRACE, "==>free_oc(): '%s'\n", 
                        BACKSQL_OC_NAME( oc ), 0, 0 );
-       avl_free( oc->attrs, (AVL_FREE)backsql_free_attr );
+       avl_free( oc->attrs, backsql_free_attr );
        ch_free( oc->keytbl.bv_val );
        ch_free( oc->keycol.bv_val );
        if ( oc->create_proc != NULL ) {
@@ -592,8 +590,8 @@ int
 backsql_destroy_schema_map( backsql_info *si )
 {
        Debug( LDAP_DEBUG_TRACE, "==>destroy_schema_map()\n", 0, 0, 0 );
-       avl_free( si->oc_by_oc, NULL );
-       avl_free( si->oc_by_id, (AVL_FREE)backsql_free_oc );
+       avl_free( si->oc_by_oc, 0 );
+       avl_free( si->oc_by_id, backsql_free_oc );
        Debug( LDAP_DEBUG_TRACE, "<==destroy_schema_map()\n", 0, 0, 0 );
        return 0;
 }
index b5fefff7ff210bf6023bfacb77c01f773ca2cb5f..c5f67a8bcef411bbbe711808a276a61d84ea9640 100644 (file)
@@ -799,9 +799,11 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
        return ( query->bv_val == NULL ? 1 : 0 );
 }
 
-int
-backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
+static int
+backsql_oc_get_candidates( void *v_oc, void *v_bsi )
 {
+       backsql_oc_map_rec *oc  = v_oc;
+       backsql_srch_info  *bsi = v_bsi;
        struct berval           query;
        SQLHSTMT                sth;
        RETCODE                 rc;
@@ -1128,7 +1130,7 @@ backsql_search(
         */
        srch_info.n_candidates = ( isroot ? -2 : limit->lms_s_unchecked == -1 
                        ? -2 : limit->lms_s_unchecked );
-       avl_apply( bi->oc_by_oc, (AVL_APPLY)backsql_oc_get_candidates,
+       avl_apply( bi->oc_by_oc, backsql_oc_get_candidates,
                        &srch_info, BACKSQL_STOP, AVL_INORDER );
        if ( !isroot && limit->lms_s_unchecked != -1 ) {
                if ( srch_info.n_candidates == -1 ) {
index f6d3a81cf490899c1f6b02df575ccdf9926bc59a..b86d4da825f7308e82d84453919431b17f2b8dd2 100644 (file)
@@ -253,8 +253,9 @@ backsql_FreeRow( BACKSQL_ROW_NTS *row )
 }
 
 static int
-backsql_cmp_connid( backsql_db_conn *c1, backsql_db_conn *c2 )
+backsql_cmp_connid( const void *v_c1, const void *v_c2 )
 {
+       const backsql_db_conn *c1 = v_c1, *c2 = v_c2;
        if ( c1->ldap_cid > c2->ldap_cid ) {
                return 1;
        }
@@ -390,7 +391,7 @@ backsql_open_db_conn( backsql_info *si, int ldap_cid, backsql_db_conn **pdbc )
        Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(): "
                "connected, adding to tree\n", 0, 0, 0 );
        ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
-       avl_insert( &si->db_conns, dbc, (AVL_CMP)backsql_cmp_connid, NULL );
+       avl_insert( &si->db_conns, dbc, backsql_cmp_connid, NULL );
        ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
        Debug( LDAP_DEBUG_TRACE, "<==backsql_open_db_conn()\n", 0, 0, 0 );
 
@@ -408,8 +409,7 @@ backsql_free_db_conn( Backend *be, Connection *ldapc )
        Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_conn()\n", 0, 0, 0 );
        tmp.ldap_cid = ldapc->c_connid;
        ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
-       conn = (backsql_db_conn *)avl_delete( &si->db_conns, &tmp,
-                       (AVL_CMP)backsql_cmp_connid );
+       conn = avl_delete( &si->db_conns, &tmp, backsql_cmp_connid );
        ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
 
        /*
@@ -444,8 +444,7 @@ backsql_get_db_conn( Backend *be, Connection *ldapc, SQLHDBC *dbh )
         * we have one thread per connection, as I understand -- 
         * so we do not need locking here
         */
-       dbc = (backsql_db_conn *)avl_find( si->db_conns, &tmp,
-                       (AVL_CMP)backsql_cmp_connid );
+       dbc = avl_find( si->db_conns, &tmp, backsql_cmp_connid );
        if ( !dbc ) {
                rc = backsql_open_db_conn( si, ldapc->c_connid, &dbc );
                if ( rc != LDAP_SUCCESS) {
index 124ec7c42274eea6f3849fb79cd1eb35bde903c9..d324815388f5741c098c269f0b11ca5cf184b451 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* backend.c - routines for dealing with back-end databases */
 
 #include <ac/string.h>
 #include <ac/socket.h>
-
 #include <sys/stat.h>
 
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 #include "lutil.h"
 #include "lber_pvt.h"
 
@@ -686,12 +688,52 @@ backend_unbind(
        Operation    *op
 )
 {
-       int     i;
+       int             i;
+#if defined( LDAP_SLAPI )
+       Slapi_PBlock *pb = op->o_pb;
+
+       int     rc;
+       slapi_x_connection_set_pb( pb, conn );
+       slapi_x_operation_set_pb( pb, op );
+#endif /* defined( LDAP_SLAPI ) */
 
        for ( i = 0; i < nbackends; i++ ) {
+#if defined( LDAP_SLAPI )
+               slapi_pblock_set( pb, SLAPI_BACKEND, (void *)&backends[i] );
+               rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN,
+                               (Slapi_PBlock *)pb );
+               if ( rc != 0 ) {
+                       /*
+                        * A preoperation plugin failure will abort the
+                        * entire operation.
+                        */
+#ifdef NEW_LOGGING
+                       LDAP_LOG( OPERATION, INFO, "do_bind: Unbind preoperation plugin "
+                                       "failed\n", 0, 0, 0);
+#else
+                       Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preoperation plugin "
+                                       "failed.\n", 0, 0, 0);
+#endif
+                       return 0;
+               }
+#endif /* defined( LDAP_SLAPI ) */
+
                if ( backends[i].be_unbind ) {
                        (*backends[i].be_unbind)( &backends[i], conn, op );
                }
+
+#if defined( LDAP_SLAPI )
+               if ( doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN,
+                               (Slapi_PBlock *)pb ) != 0 ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( OPERATION, INFO, "do_unbind: Unbind postoperation plugins "
+                                       "failed\n", 0, 0, 0);
+#else
+                       Debug(LDAP_DEBUG_TRACE, "do_unbind: Unbind postoperation plugins "
+                                       "failed.\n", 0, 0, 0);
+#endif
+               }
+#endif /* defined( LDAP_SLAPI ) */
        }
 
        return 0;
@@ -828,6 +870,15 @@ backend_check_restrictions(
                        }
                }
 
+#ifdef LDAP_EXOP_X_CANCEL
+               {
+                       struct berval bv = BER_BVC( LDAP_EXOP_X_CANCEL );
+                       if ( bvmatch( opdata, &bv ) ) {
+                               break;
+                       }
+               }
+#endif
+
                /* treat everything else as a modify */
                opflag = SLAP_RESTRICT_OP_MODIFY;
                updateop++;
index eb58fbbaa03a3c819d50518b261690b96b201631..8ffccd74f5f1a9ccebd01e72f0b802c8bb67b3d3 100644 (file)
@@ -1,7 +1,7 @@
 /* backglue.c - backend glue routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 2001-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2001-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -29,6 +29,7 @@
 
 #include <stdio.h>
 
+#include <ac/string.h>
 #include <ac/socket.h>
 
 #define SLAPD_TOOLS
@@ -274,6 +275,31 @@ glue_back_sendentry (
        return rc;
 }
 
+static int
+glue_back_sendreference (
+       BackendDB *be,
+       Connection *c,
+       Operation *op,
+       Entry *e,
+       BerVarray bv,
+       LDAPControl **ctrls,
+       BerVarray *v2
+)
+{
+       slap_callback *tmp = op->o_callback;
+       glue_state *gs = tmp->sc_private;
+       int rc;
+
+       op->o_callback = gs->prevcb;
+       if (op->o_callback && op->o_callback->sc_sendreference) {
+               rc = op->o_callback->sc_sendreference( be, c, op, e, bv, ctrls, v2 );
+       } else {
+               rc = send_search_reference( be, c, op, e, bv, ctrls, v2 );
+       }
+       op->o_callback = tmp;
+       return rc;
+}
+
 static int
 glue_back_search (
        BackendDB *b0,
@@ -295,7 +321,7 @@ glue_back_search (
        BackendDB *be;
        int i, rc = 0, t2limit = 0, s2limit = 0;
        long stoptime = 0;
-       glue_state gs = {0};
+       glue_state gs = {0, 0, 0, NULL, 0, NULL, NULL};
        slap_callback cb;
 
        cb.sc_response = glue_back_response;
@@ -379,7 +405,23 @@ glue_back_search (
                                        s2limit, t2limit, filter, filterstr,
                                        attrs, attrsonly);
                        }
+
+                       switch ( gs.err ) {
+
+                       /*
+                        * Add errors that should result in dropping
+                        * the search
+                        */
+                       case LDAP_SIZELIMIT_EXCEEDED:
+                       case LDAP_TIMELIMIT_EXCEEDED:
+                       case LDAP_ADMINLIMIT_EXCEEDED:
+                               goto end_of_loop;
+                       
+                       default:
+                               break;
+                       }
                }
+end_of_loop:;
                break;
        }
        op->o_callback = gs.prevcb;
index 1b3220c2c39080bd13a8a0a9b2d226d568eaed07..6316a9878a1f05adbcd93b879bfe676f6679f1d6 100644 (file)
@@ -1,7 +1,7 @@
 /* bind.c - decode an ldap bind operation and pass it to a backend db */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
+
 
 int
 do_bind(
@@ -47,6 +51,10 @@ do_bind(
        struct berval cred = { 0, NULL };
        Backend *be = NULL;
 
+#ifdef LDAP_SLAPI
+       Slapi_PBlock *pb = op->o_pb;
+#endif
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_bind: conn %d\n", conn->c_connid, 0, 0 );
 #else
@@ -62,7 +70,7 @@ do_bind(
        /* log authorization identity demotion */
        if ( conn->c_dn.bv_len ) {
                Statslog( LDAP_DEBUG_STATS,
-                       "conn=%lu op=%lu AUTHZ anonymous mech=implicit ssf=0",
+                       "conn=%lu op=%lu BIND anonymous mech=implicit ssf=0",
                        op->o_connid, op->o_opid, 0, 0, 0 );
        }
 
@@ -97,8 +105,8 @@ do_bind(
         *      }
         *
         *      SaslCredentials ::= SEQUENCE {
-     *         mechanism           LDAPString,
-     *         credentials         OCTET STRING OPTIONAL
+        *              mechanism           LDAPString,
+        *              credentials         OCTET STRING OPTIONAL
         *      }
         */
 
@@ -325,18 +333,23 @@ do_bind(
 
                        /* log authorization identity */
                        Statslog( LDAP_DEBUG_STATS,
-                               "conn=%lu op=%lu AUTHZ dn=\"%s\" mech=%s ssf=%d\n",
+                               "conn=%lu op=%lu BIND dn=\"%s\" mech=%s ssf=%d\n",
                                op->o_connid, op->o_opid,
-                               conn->c_dn.bv_val, conn->c_authmech.bv_val, ssf );
+                               conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
+                               conn->c_authmech.bv_val, ssf );
 
 #ifdef NEW_LOGGING
                        LDAP_LOG( OPERATION, DETAIL1, 
                                "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
-                               conn->c_authmech.bv_val, conn->c_dn.bv_val, ssf );
+                               conn->c_authmech.bv_val,
+                               conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
+                               ssf );
 #else
                        Debug( LDAP_DEBUG_TRACE,
                                "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
-                               conn->c_authmech.bv_val, conn->c_dn.bv_val, ssf );
+                               conn->c_authmech.bv_val,
+                               conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
+                               ssf );
 #endif
 
                } else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
@@ -526,6 +539,69 @@ do_bind(
                goto cleanup;
        }
 
+#if defined( LDAP_SLAPI )
+       slapi_x_backend_set_pb( pb, be );
+       slapi_x_connection_set_pb( pb, conn );
+       slapi_x_operation_set_pb( pb, op );
+       slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method );
+       slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&cred );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_BIND_FN, pb );
+       if ( rc != SLAPI_BIND_SUCCESS ) {
+               /*
+                * Binding is a special case for SLAPI plugins. It is
+                * possible for a bind plugin to be successful *and*
+                * abort further processing; this means it has handled
+                * a bind request authoritatively. If we have reached
+                * here, a result has been sent to the client (XXX
+                * need to check with Sun whether SLAPI_BIND_ANONYMOUS
+                * means a result has been sent).
+                */
+               int ldapRc;
+
+               if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&ldapRc ) != 0 )
+                       ldapRc = LDAP_OTHER;
+
+               edn.bv_val = NULL;
+               edn.bv_len = 0;
+               if ( rc != SLAPI_BIND_FAIL && ldapRc == LDAP_SUCCESS ) {
+                       /* Set the new connection DN. */
+                       if ( rc != SLAPI_BIND_ANONYMOUS ) {
+                               slapi_pblock_get( pb, SLAPI_CONN_DN, (void *)&edn.bv_val );
+                       }
+                       rc = dnPrettyNormal( NULL, &edn, &pdn, &ndn );
+                       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+                       conn->c_dn = pdn;
+                       conn->c_ndn = ndn;
+                       pdn.bv_val = NULL;
+                       pdn.bv_len = 0;
+                       ndn.bv_val = NULL;
+                       ndn.bv_len = 0;
+                       if ( conn->c_dn.bv_len != 0 ) {
+                               ber_len_t max = sockbuf_max_incoming_auth;
+                               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
+                       }
+                       /* log authorization identity */
+                       Statslog( LDAP_DEBUG_STATS,
+                               "conn=%lu op=%lu BIND dn=\"%s\" mech=simple (SLAPI) ssf=0\n",
+                               op->o_connid, op->o_opid,
+                               conn->c_dn.bv_val, 0, 0 );
+                       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+               }
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_bind: Bind preoperation plugin returned %d\n",
+                               rc, 0, 0);
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_bind: Bind preoperation plugin returned %d.\n",
+                               rc, 0, 0);
+#endif
+               rc = ldapRc;
+               goto cleanup;
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        if ( be->be_bind ) {
                int ret;
 
@@ -562,7 +638,7 @@ do_bind(
 
                        /* log authorization identity */
                        Statslog( LDAP_DEBUG_STATS,
-                               "conn=%lu op=%lu AUTHZ dn=\"%s\" mech=simple ssf=0\n",
+                               "conn=%lu op=%lu BIND dn=\"%s\" mech=simple ssf=0\n",
                                op->o_connid, op->o_opid,
                                conn->c_dn.bv_val, conn->c_authmech.bv_val, 0 );
 
@@ -592,6 +668,18 @@ do_bind(
                        NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       if ( doPluginFNs( be, SLAPI_PLUGIN_POST_BIND_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_bind: Bind postoperation plugins failed\n",
+                               0, 0, 0);
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_bind: Bind postoperation plugins failed.\n",
+                               0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        conn->c_sasl_bindop = NULL;
 
diff --git a/servers/slapd/cancel.c b/servers/slapd/cancel.c
new file mode 100644 (file)
index 0000000..fc2832b
--- /dev/null
@@ -0,0 +1,134 @@
+/* $OpenLDAP$ */
+/* cancel.c - LDAP cancel extended operation */
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/krb.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+
+#include "slap.h"
+
+#ifdef LDAP_EXOP_X_CANCEL
+
+#include <lber_pvt.h>
+#include <lutil.h>
+
+int cancel_extop(
+       Connection *conn,
+       Operation *op,
+       const char *reqoid,
+       struct berval *reqdata,
+       char **rspoid,
+       struct berval **rspdata,
+       LDAPControl ***rspctrls,
+       const char **text,
+       BerVarray *refs )
+{
+       Backend *be;
+       int rc;
+       int found = 0;
+       int opid;
+       BerElement *ber;
+       int i;
+
+       assert( reqoid != NULL );
+       assert( strcmp( LDAP_EXOP_X_CANCEL, reqoid ) == 0 );
+
+       if ( reqdata == NULL ) {
+               *text = "no message ID supplied";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       ber = ber_init( reqdata );
+       if ( ber == NULL ) {
+               *text = "internal error";
+               return LDAP_OTHER;
+       }
+
+       if ( ber_scanf( ber, "{i}", &opid ) == LBER_ERROR ) {
+               *text = "message ID parse failed";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       (void) ber_free( ber, 1 );
+
+       if ( opid < 0 ) {
+               *text = "message ID invalid";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+       LDAP_STAILQ_FOREACH( op, &conn->c_pending_ops, o_next ) {
+               if ( op->o_msgid == opid ) {
+                       LDAP_STAILQ_REMOVE( &conn->c_pending_ops, op, slap_op, o_next );
+                       slap_op_free( op );
+                       found = 1;
+                       break;
+               }
+       }
+       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+       if ( found )
+               return LDAP_SUCCESS;
+
+       found = 0;
+       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+       LDAP_STAILQ_FOREACH( op, &conn->c_ops, o_next ) {
+               if ( op->o_msgid == opid ) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if ( !found ) {
+#ifdef LDAP_SYNC
+               for ( i = 0; i < nbackends; i++ ) {
+                       if ( strncmp( backends[i].be_type, "bdb", 3 ) ) continue;
+                       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+                       if ( bdb_cancel( &backends[i], conn, opid ) == LDAP_SUCCESS ) {
+                               return LDAP_SUCCESS;
+                       } else {
+                               *text = "message ID not found";
+                               return LDAP_NO_SUCH_OPERATION;
+                       }
+               }
+#else
+               *text = "message ID not found";
+               ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+               return LDAP_NO_SUCH_OPERATION;
+#endif
+       }
+
+       if ( op->o_cancel != LDAP_CANCEL_NONE ) {
+               *text = "message ID already being cancelled";
+               ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       op->o_cancel = LDAP_CANCEL_REQ;
+       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+       while ( op->o_cancel == LDAP_CANCEL_REQ ) {
+               ldap_pvt_thread_yield();
+       }
+
+       if ( op->o_cancel == LDAP_CANCEL_ACK ) {
+               rc = LDAP_SUCCESS;
+       } else {
+               rc = op->o_cancel;
+       }
+
+       op->o_cancel = LDAP_CANCEL_DONE;
+
+       return rc;
+}
+
+#endif /* LDAP_EXOP_X_CANCEL */
index 81e3e9f54e206783b54226bbe957f3b67fe4b4fa..1f1681eb517d6944db2b537d78a4b7b84104a83c 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -22,6 +22,9 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 
 static int compare_entry(
        Connection *conn,
@@ -42,12 +45,16 @@ do_compare(
        struct berval ndn = { 0, NULL };
        struct berval desc = { 0, NULL };
        struct berval value = { 0, NULL };
-       AttributeAssertion ava = { 0 };
+       AttributeAssertion ava = { NULL, { 0, NULL } };
        Backend *be;
        int rc = LDAP_SUCCESS;
        const char *text = NULL;
        int manageDSAit;
 
+#ifdef LDAP_SLAPI
+       Slapi_PBlock *pb = op->o_pb;
+#endif
+
        ava.aa_desc = NULL;
 
 #ifdef NEW_LOGGING
@@ -267,6 +274,34 @@ do_compare(
        /* deref suffix alias if appropriate */
        suffix_alias( be, &ndn );
 
+#if defined( LDAP_SLAPI )
+       slapi_x_backend_set_pb( pb, be );
+       slapi_x_connection_set_pb( pb, conn );
+       slapi_x_operation_set_pb( pb, op );
+       slapi_pblock_set( pb, SLAPI_COMPARE_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+       slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, (void *)desc.bv_val );
+       slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, (void *)&value );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_COMPARE_FN, pb );
+       if ( rc != 0 ) {
+               /*
+                * A preoperation plugin failure will abort the
+                * entire operation.
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_compare: compare preoperation plugin "
+                               "failed\n", 0, 0, 0);
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_compare: compare preoperation plugin "
+                               "failed.\n", 0, 0, 0);
+#endif
+               if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0)
+                       rc = LDAP_OTHER;
+               goto cleanup;
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        if ( be->be_compare ) {
                (*be->be_compare)( be, conn, op, &pdn, &ndn, &ava );
        } else {
@@ -275,6 +310,18 @@ do_compare(
                        NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       if ( doPluginFNs( be, SLAPI_PLUGIN_POST_COMPARE_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_compare: compare postoperation plugins "
+                               "failed\n", 0, 0, 0 );
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_compare: compare postoperation plugins "
+                               "failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        free( pdn.bv_val );
        free( ndn.bv_val );
index 91c565f1ec2bd2d8c5f970561b26162a56abf0be..2c66a841b46c61370f3c08e163c437fe9ce77a7f 100644 (file)
@@ -1,7 +1,7 @@
 /* config.c - configuration file handling routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -18,6 +18,9 @@
 #include "lutil.h"
 #include "ldap_pvt.h"
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 
 #define ARGS_STEP      512
 
@@ -30,7 +33,9 @@ struct slap_limits_set deflimit = {
 
        SLAPD_DEFAULT_SIZELIMIT,        /* backward compatible limits */
        0,
-       -1                              /* no limit on unchecked size */
+       -1,                             /* no limit on unchecked size */
+       0,                              /* page limit */
+       0                               /* hide number of entries left */
 };
 
 AccessControl  *global_acl = NULL;
@@ -63,11 +68,7 @@ char   *slapd_args_file = NULL;
 
 char   *strtok_quote_ptr;
 
-#ifdef SLAPD_RLOOKUPS
-int use_reverse_lookup = 1;
-#else /* !SLAPD_RLOOKUPS */
 int use_reverse_lookup = 0;
-#endif /* !SLAPD_RLOOKUPS */
 
 static char    *fp_getline(FILE *fp, int *lineno);
 static void    fp_getline_init(int *lineno);
@@ -559,12 +560,10 @@ read_config( const char *fname, int depth )
 
                        lutil_salt_format( cargv[1] );
 
-#ifdef HAVE_CYRUS_SASL
                /* SASL config options */
                } else if ( strncasecmp( cargv[0], "sasl", 4 ) == 0 ) {
                        if ( slap_sasl_config( cargc, cargv, line, fname, lineno ) )
                                return 1;
-#endif /* HAVE_CYRUS_SASL */
 
                } else if ( strcasecmp( cargv[0], "schemadn" ) == 0 ) {
                        struct berval dn;
@@ -963,20 +962,6 @@ read_config( const char *fname, int depth )
                        struct berval alias, palias, nalias;
                        struct berval aliased, paliased, naliased;
 
-                       if( 1 ) {
-#ifdef NEW_LOGGING
-                               LDAP_LOG( CONFIG, CRIT, 
-                                       "%s: line %d: suffixAlias is no longer supported.\n",
-                                       fname, lineno, 0 );
-#else
-                               Debug( LDAP_DEBUG_ANY,
-                                       "%s: line %d: suffixAlias is no longer supported.\n",
-                                       fname, lineno, 0 );
-#endif
-
-                               return( 1 );
-                       }
-
                        if ( cargc < 2 ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT, 
@@ -1703,6 +1688,13 @@ read_config( const char *fname, int depth )
 
                        }
 
+               /* define attribute option(s) */
+               } else if ( strcasecmp( cargv[0], "attributeoptions" ) == 0 ) {
+                       ad_define_option( NULL, NULL, 0 );
+                       for ( i = 1; i < cargc; i++ )
+                               if ( ad_define_option( cargv[i], fname, lineno ) != 0 )
+                                       return 1;
+
                /* turn on/off schema checking */
                } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
                        if ( cargc < 2 ) {
@@ -2325,6 +2317,74 @@ read_config( const char *fname, int depth )
 #endif
 #endif /* !SLAPD_RLOOKUPS */
 
+               /* Netscape plugins */
+               } else if ( strcasecmp( cargv[0], "plugin" ) == 0 ) {
+#if defined( LDAP_SLAPI )
+
+#ifdef notdef /* allow global plugins, too */
+                       /*
+                        * a "plugin" line must be inside a database
+                        * definition, since we implement pre-,post- 
+                        * and extended operation plugins
+                        */
+                       if ( be == NULL ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, INFO, 
+                                       "%s: line %d: plugin line must appear "
+                                       "inside a database definition.\n",
+                                       fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: plugin "
+                                   "line must appear inside a database "
+                                   "definition\n", fname, lineno, 0 );
+#endif
+                               return( 1 );
+                       }
+#endif /* notdef */
+
+                       if ( netscape_plugin( be, fname, lineno, cargc, cargv ) 
+                                       != LDAP_SUCCESS ) {
+                               return( 1 );
+                       }
+
+#else /* !defined( LDAP_SLAPI ) */
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONFIG, INFO, 
+                               "%s: line %d: SLAPI not supported.\n",
+                               fname, lineno, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, "%s: line %d: SLAPI "
+                           "not supported.\n", fname, lineno, 0 );
+#endif
+                       return( 1 );
+                       
+#endif /* !defined( LDAP_SLAPI ) */
+
+               /* Netscape plugins */
+               } else if ( strcasecmp( cargv[0], "pluginlog" ) == 0 ) {
+#if defined( LDAP_SLAPI )
+                       if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, INFO, 
+                                       "%s: line %d: missing file name "
+                                       "in pluginlog <filename> line.\n",
+                                       fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY, 
+                                       "%s: line %d: missing file name "
+                                       "in pluginlog <filename> line.\n",
+                                       fname, lineno, 0 );
+#endif
+                               return( 1 );
+                       }
+
+                       if ( slapi_log_file != NULL ) {
+                               ch_free( slapi_log_file );
+                       }
+
+                       slapi_log_file = ch_strdup( cargv[1] );
+#endif /* !defined( LDAP_SLAPI ) */
+
                /* pass anything else to the current backend info/db config routine */
                } else {
                        if ( bi != NULL ) {
index 944105015605f1166e3719817f3c70d1afc44f3f..f5fe518b7745e7cf9771778924e01ddefa969887 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -395,22 +395,31 @@ long connection_init(
        if( c == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( CONNECTION, INFO, 
-                          "connection_init: skt %d      connection table full (%d/%d)\n",
-                          s, i, dtblsize );
+                          "connection_init: skt %d connection table full "
+                          "(%d/%d)\n", s, i, dtblsize );
 #else
                Debug( LDAP_DEBUG_ANY,
-                               "connection_init(%d): connection table full (%d/%d)\n",
-                               s, i, dtblsize);
+                               "connection_init(%d): connection table full "
+                               "(%d/%d)\n", s, i, dtblsize);
 #endif
            ldap_pvt_thread_mutex_unlock( &connections_mutex );
            return -1;
        }
-    }
+       }
 #endif
 
-    assert( c != NULL );
+       assert( c != NULL );
 
        if( c->c_struct_state == SLAP_C_UNINITIALIZED ) {
+               c->c_send_ldap_result = slap_send_ldap_result;
+               c->c_send_search_entry = slap_send_search_entry;
+               c->c_send_search_result = slap_send_search_result;
+               c->c_send_search_reference = slap_send_search_reference;
+               c->c_send_ldap_extended = slap_send_ldap_extended;
+#ifdef LDAP_RES_INTERMEDIATE_RESP
+               c->c_send_ldap_intermediate_resp = slap_send_ldap_intermediate_resp;
+#endif
+
                c->c_authmech.bv_val = NULL;
                c->c_authmech.bv_len = 0;
                c->c_dn.bv_val = NULL;
@@ -1018,6 +1027,18 @@ operations_error:
 #endif /* SLAPD_MONITOR */
        ldap_pvt_thread_mutex_unlock( &num_ops_mutex );
 
+#ifdef LDAP_EXOP_X_CANCEL
+       if ( arg->co_op->o_cancel == LDAP_CANCEL_REQ ) {
+               arg->co_op->o_cancel = LDAP_TOO_LATE;
+       }
+
+       while ( arg->co_op->o_cancel != LDAP_CANCEL_NONE &&
+               arg->co_op->o_cancel != LDAP_CANCEL_DONE )
+       {
+               ldap_pvt_thread_yield();
+       }
+#endif
+
        ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
        conn->c_n_ops_executing--;
@@ -1025,12 +1046,26 @@ operations_error:
 
        LDAP_STAILQ_REMOVE( &conn->c_ops, arg->co_op, slap_op, o_next);
        LDAP_STAILQ_NEXT(arg->co_op, o_next) = NULL;
+
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+       if ( arg->co_op->o_cancel == LDAP_CANCEL_ACK )
+               goto co_op_free;
+#endif
 #ifdef LDAP_CLIENT_UPDATE
-       if ( !( arg->co_op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
-#endif /* LDAP_CLIENT_UPDATE */
-       {
-               slap_op_free( arg->co_op );
-       }
+       if ( ( arg->co_op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
+               goto no_co_op_free;
+#endif
+#ifdef LDAP_SYNC
+       if ( ( arg->co_op->o_sync_mode & SLAP_SYNC_PERSIST ) )
+               goto no_co_op_free;
+#endif
+
+co_op_free:
+
+       slap_op_free( arg->co_op );
+
+no_co_op_free:
+
        arg->co_op = NULL;
        arg->co_conn = NULL;
        free( (char *) arg );
@@ -1400,14 +1435,49 @@ connection_input(
 
        op->o_conn = conn;
        op->vrFilter = NULL;
+#ifdef LDAP_CONTROL_PAGEDRESULTS
        op->o_pagedresults_state = conn->c_pagedresults_state;
+#endif
 #ifdef LDAP_CONNECTIONLESS
        op->o_peeraddr = peeraddr;
        if (cdn ) {
            ber_str2bv( cdn, 0, 1, &op->o_dn );
            op->o_protocol = LDAP_VERSION2;
        }
+       if (conn->c_is_udp) {
+               int rc;
+
+               op->o_res_ber = ber_alloc_t( LBER_USE_DER );
+               if (op->o_res_ber == NULL)
+                       return 1;
+
+               rc = ber_write(op->o_res_ber, (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
+               if (rc != sizeof(struct sockaddr)) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONNECTION, INFO, 
+                               "connection_input: conn %lu  ber_write failed\n",
+                               conn->c_connid, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
 #endif
+                       return 1;
+               }
+
+               if (conn->c_protocol == LDAP_VERSION2) {
+                       rc = ber_printf(op->o_res_ber, "{i{" /*}}*/, op->o_msgid);
+                       if (rc == -1) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONNECTION, INFO, 
+                                       "connection_input: conn %lu  put outer sequence failed\n",
+                                       conn->c_connid, 0, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
+#endif
+                               return rc;
+                       }
+               }
+       }
+#endif /* LDAP_CONNECTIONLESS */
 
        if ( conn->c_conn_state == SLAP_C_BINDING
                || conn->c_conn_state == SLAP_C_CLOSING )
index 3ce7d9ebd7390355cb915624ce9dcf15d30ea0c0..56187c587aeff23662aaed8d4dd819a0c7229dec 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /* 
- * Copyright 1999-2002 The OpenLDAP Foundation.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -44,18 +44,65 @@ typedef int (SLAP_CTRL_PARSE_FN) LDAP_P((
        LDAPControl *ctrl,
        const char **text ));
 
+static SLAP_CTRL_PARSE_FN parseProxyAuthz;
 static SLAP_CTRL_PARSE_FN parseManageDSAit;
-static SLAP_CTRL_PARSE_FN parseSubentries;
 static SLAP_CTRL_PARSE_FN parseNoOp;
 static SLAP_CTRL_PARSE_FN parsePagedResults;
 static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
+static SLAP_CTRL_PARSE_FN parsePermitModify;
+static SLAP_CTRL_PARSE_FN parseNoReferrals;
 
+#ifdef LDAP_CONTROL_SUBENTRIES
+static SLAP_CTRL_PARSE_FN parseSubentries;
+#endif
 #ifdef LDAP_CLIENT_UPDATE
 static SLAP_CTRL_PARSE_FN parseClientUpdate;
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#ifdef LDAP_SYNC
+static SLAP_CTRL_PARSE_FN parseLdupSync;
+#endif
 
 #undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
 
+static char *proxy_authz_extops[] = {
+       LDAP_EXOP_MODIFY_PASSWD,
+       LDAP_EXOP_X_WHO_AM_I,
+       NULL
+};
+
+/*
+ * all known request control OIDs should be added to this list
+ */
+char *slap_known_controls[] = {
+       LDAP_CONTROL_MANAGEDSAIT,
+       LDAP_CONTROL_PROXY_AUTHZ,
+
+#ifdef LDAP_CONTROL_SUBENTRIES
+       LDAP_CONTROL_SUBENTRIES,
+#endif /* LDAP_CONTROL_SUBENTRIES */
+
+       LDAP_CONTROL_NOOP,
+
+#ifdef LDAP_CONTROL_DUPENT_REQUEST
+       LDAP_CONTROL_DUPENT_REQUEST,
+#endif /* LDAP_CONTROL_DUPENT_REQUEST */
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+       LDAP_CONTROL_PAGEDRESULTS,
+#endif
+
+#ifdef LDAP_CONTROL_SORTREQUEST
+       LDAP_CONTROL_SORTREQUEST,
+#endif /* LDAP_CONTROL_SORTREQUEST */
+
+#ifdef LDAP_CONTROL_VLVREQUEST
+       LDAP_CONTROL_VLVREQUEST,
+#endif /* LDAP_CONTROL_VLVREQUEST */
+
+       LDAP_CONTROL_VALUESRETURNFILTER,
+       NULL
+};
+
 static struct slap_control {
        char *sc_oid;
        slap_mask_t sc_mask;
@@ -63,35 +110,49 @@ static struct slap_control {
        SLAP_CTRL_PARSE_FN *sc_parse;
 
 } supportedControls[] = {
-       { LDAP_CONTROL_MANAGEDSAIT,
-               SLAP_CTRL_ACCESS, NULL,
-               parseManageDSAit },
+       { LDAP_CONTROL_VALUESRETURNFILTER,
+               SLAP_CTRL_SEARCH, NULL,
+               parseValuesReturnFilter },
 #ifdef LDAP_CONTROL_SUBENTRIES
        { LDAP_CONTROL_SUBENTRIES,
                SLAP_CTRL_SEARCH, NULL,
                parseSubentries },
 #endif
-#ifdef LDAP_CONTROL_NOOP
        { LDAP_CONTROL_NOOP,
                SLAP_CTRL_ACCESS, NULL,
                parseNoOp },
-#endif
-#ifdef LDAP_CONTROL_PAGEDRESULTS_REQUEST
-       { LDAP_CONTROL_PAGEDRESULTS_REQUEST,
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+       { LDAP_CONTROL_PAGEDRESULTS,
                SLAP_CTRL_SEARCH, NULL,
                parsePagedResults },
 #endif
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
-       { LDAP_CONTROL_VALUESRETURNFILTER,
-               SLAP_CTRL_SEARCH, NULL,
-               parseValuesReturnFilter },
+       { LDAP_CONTROL_MANAGEDSAIT,
+               SLAP_CTRL_ACCESS, NULL,
+               parseManageDSAit },
+       { LDAP_CONTROL_PROXY_AUTHZ,
+               SLAP_CTRL_FRONTEND|SLAP_CTRL_ACCESS, proxy_authz_extops,
+               parseProxyAuthz },
+#ifdef LDAP_CONTROL_PERMITMODIFY
+       { LDAP_CONTROL_PERMITMODIFY,
+               SLAP_CTRL_UPDATE, NULL,
+               parsePermitModify },
+#endif
+#ifdef LDAP_CONTROL_NOREFERRALS
+       { LDAP_CONTROL_NOREFERRALS,
+               SLAP_CTRL_SEARCH, NULL,
+               parseNoReferrals },
 #endif
 #ifdef LDAP_CLIENT_UPDATE
        { LDAP_CONTROL_CLIENT_UPDATE,
                SLAP_CTRL_SEARCH, NULL,
                parseClientUpdate },
-#endif /* LDAP_CLIENT_UPDATE */
-       { NULL }
+#endif
+#ifdef LDAP_SYNC
+       { LDAP_CONTROL_SYNC,
+               SLAP_CTRL_SEARCH, NULL,
+               parseLdupSync },
+#endif
+       { NULL, 0, NULL, 0 }
 };
 
 char *
@@ -100,6 +161,12 @@ get_supported_ctrl(int index)
        return supportedControls[index].sc_oid;
 }
 
+slap_mask_t
+get_supported_ctrl_mask(int index)
+{
+       return supportedControls[index].sc_mask;
+}
+
 static struct slap_control *
 find_ctrl( const char *oid )
 {
@@ -340,8 +407,19 @@ int get_ctrls(
                                tagmask = SLAP_CTRL_ABANDON;
                                break;
                        case LDAP_REQ_EXTENDED:
-                               /* FIXME: check list of extended operations */
-                               tagmask = ~0U;
+                               tagmask=~0L;
+                               assert( op->o_extendedop != NULL );
+                               if( sc->sc_extendedops != NULL ) {
+                                       int i;
+                                       for( i=0; sc->sc_extendedops[i] != NULL; i++ ) {
+                                               if( strcmp( op->o_extendedop, sc->sc_extendedops[i] )
+                                                       == 0 )
+                                               {
+                                                       tagmask=0L;
+                                                       break;
+                                               }
+                                       }
+                               }
                                break;
                        default:
                                rc = LDAP_OTHER;
@@ -391,9 +469,11 @@ int get_ctrls(
 return_results:
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, RESULTS, 
-               "get_ctrls: n=%d rc=%d err=%s\n", nctrls, rc, errmsg ? errmsg : "" );
+               "get_ctrls: n=%d rc=%d err=\"%s\"\n",
+               nctrls, rc, errmsg ? errmsg : "" );
 #else
-       Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: n=%d rc=%d err=%s\n",
+       Debug( LDAP_DEBUG_TRACE,
+               "<= get_ctrls: n=%d rc=%d err=\"%s\"\n",
                nctrls, rc, errmsg ? errmsg : "");
 #endif
 
@@ -432,38 +512,108 @@ static int parseManageDSAit (
        return LDAP_SUCCESS;
 }
 
-#ifdef LDAP_CONTROL_SUBENTRIES
-static int parseSubentries (
+static int parseProxyAuthz (
        Connection *conn,
        Operation *op,
        LDAPControl *ctrl,
        const char **text )
 {
-       if ( op->o_subentries != SLAP_NO_CONTROL ) {
-               *text = "subentries control specified multiple times";
-               return LDAP_PROTOCOL_ERROR;
-       }
+       int rc;
+       struct berval dn = { 0, NULL };
 
-       /* FIXME: should use BER library */
-       if( ( ctrl->ldctl_value.bv_len != 3 )
-               && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
-               && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
-       {
-               *text = "subentries control value encoding is bogus";
+       if ( op->o_proxy_authz != SLAP_NO_CONTROL ) {
+               *text = "proxy authorization control specified multiple times";
                return LDAP_PROTOCOL_ERROR;
        }
 
-       op->o_subentries = ctrl->ldctl_iscritical
+       op->o_proxy_authz = ctrl->ldctl_iscritical
                ? SLAP_CRITICAL_CONTROL
                : SLAP_NONCRITICAL_CONTROL;
 
-       op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, ARGS, 
+               "parseProxyAuthz: conn %lu authzid=\"%s\"\n", 
+               conn->c_connid,
+               ctrl->ldctl_value.bv_len ?  ctrl->ldctl_value.bv_val : "anonymous",
+               0 );
+#else
+       Debug( LDAP_DEBUG_ARGS,
+               "parseProxyAuthz: conn %lu authzid=\"%s\"\n", 
+               conn->c_connid,
+               ctrl->ldctl_value.bv_len ?  ctrl->ldctl_value.bv_val : "anonymous",
+               0 );
+#endif
+
+       if( ctrl->ldctl_value.bv_len == 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, RESULTS, 
+                       "parseProxyAuthz: conn=%lu anonymous\n", 
+                       conn->c_connid, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "parseProxyAuthz: conn=%lu anonymous\n", 
+                       conn->c_connid, 0, 0 );
+#endif
+
+               /* anonymous */
+               free( op->o_dn.bv_val );
+               op->o_dn.bv_len = 0;
+               op->o_dn.bv_val = ch_strdup( "" );
+
+               free( op->o_ndn.bv_val );
+               op->o_ndn.bv_len = 0;
+               op->o_ndn.bv_val = ch_strdup( "" );
+
+               return LDAP_SUCCESS;
+       }
+
+       rc = slap_sasl_getdn( conn,
+               ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len,
+               NULL, &dn, SLAP_GETDN_AUTHZID );
+
+       if( rc != LDAP_SUCCESS || !dn.bv_len ) {
+               if ( dn.bv_val ) {
+                       ch_free( dn.bv_val );
+               }
+               *text = "authzId mapping failed";
+               return LDAP_PROXY_AUTHZ_FAILURE;
+       }
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, RESULTS, 
+               "parseProxyAuthz: conn=%lu \"%s\"\n", 
+               conn->c_connid,
+               dn.bv_len ? dn.bv_val : "(NULL)", 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE,
+               "parseProxyAuthz: conn=%lu \"%s\"\n", 
+               conn->c_connid,
+               dn.bv_len ? dn.bv_val : "(NULL)", 0 );
+#endif
+
+       rc = slap_sasl_authorized( conn, &op->o_ndn, &dn );
+
+       if( rc ) {
+               ch_free( dn.bv_val );
+               *text = "not authorized to assume identity";
+               return LDAP_PROXY_AUTHZ_FAILURE;
+       }
+
+       ch_free( op->o_dn.bv_val );
+       ch_free( op->o_ndn.bv_val );
+
+       op->o_dn.bv_val = NULL;
+       op->o_ndn = dn;
+
+       /*
+        * NOTE: since slap_sasl_getdn() returns a normalized dn,
+        * from now on op->o_dn is normalized
+        */
+       ber_dupbv( &op->o_dn, &dn );
 
        return LDAP_SUCCESS;
 }
-#endif
 
-#ifdef LDAP_CONTROL_NOOP
 static int parseNoOp (
        Connection *conn,
        Operation *op,
@@ -486,9 +636,8 @@ static int parseNoOp (
 
        return LDAP_SUCCESS;
 }
-#endif
 
-#ifdef LDAP_CONTROL_PAGEDRESULTS_REQUEST
+#ifdef LDAP_CONTROL_PAGEDRESULTS
 static int parsePagedResults (
        Connection *conn,
        Operation *op,
@@ -506,7 +655,7 @@ static int parsePagedResults (
        }
 
        if ( ctrl->ldctl_value.bv_len == 0 ) {
-               *text = "paged results control value is empty";
+               *text = "paged results control value is empty (or absent)";
                return LDAP_PROTOCOL_ERROR;
        }
 
@@ -516,6 +665,7 @@ static int parsePagedResults (
         *                              -- requested page size from client
         *                              -- result set size estimate from server
         *              cookie  OCTET STRING
+        * }
         */
        ber = ber_init( &ctrl->ldctl_value );
        if( ber == NULL ) {
@@ -531,7 +681,7 @@ static int parsePagedResults (
                return LDAP_PROTOCOL_ERROR;
        }
 
-       if( size <= 0 ) {
+       if( size < 0 ) {
                *text = "paged results control size invalid";
                return LDAP_PROTOCOL_ERROR;
        }
@@ -555,9 +705,12 @@ static int parsePagedResults (
                        *text = "paged results cookie is invalid or old";
                        return LDAP_UNWILLING_TO_PERFORM;
                }
+       } else {
+               /* Initial request.  Initialize state. */
+               op->o_pagedresults_state.ps_cookie = 0;
+               op->o_pagedresults_state.ps_id = NOID;
        }
 
-       op->o_pagedresults_state.ps_cookie = op->o_opid;
        op->o_pagedresults_size = size;
 
        op->o_pagedresults = ctrl->ldctl_iscritical
@@ -568,7 +721,6 @@ static int parsePagedResults (
 }
 #endif
 
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
 int parseValuesReturnFilter (
        Connection *conn,
        Operation *op,
@@ -581,12 +733,12 @@ int parseValuesReturnFilter (
        const char *err_msg = "";
 
        if ( op->o_valuesreturnfilter != SLAP_NO_CONTROL ) {
-               *text = "valuesreturnfilter control specified multiple times";
+               *text = "valuesReturnFilter control specified multiple times";
                return LDAP_PROTOCOL_ERROR;
        }
 
        if ( ctrl->ldctl_value.bv_len == 0 ) {
-               *text = "valuesreturnfilter control value is empty";
+               *text = "valuesReturnFilter control value is empty (or absent)";
                return LDAP_PROTOCOL_ERROR;
        }
 
@@ -629,6 +781,86 @@ int parseValuesReturnFilter (
 
        return LDAP_SUCCESS;
 }
+
+#ifdef LDAP_CONTROL_SUBENTRIES
+static int parseSubentries (
+       Connection *conn,
+       Operation *op,
+       LDAPControl *ctrl,
+       const char **text )
+{
+       if ( op->o_subentries != SLAP_NO_CONTROL ) {
+               *text = "subentries control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       /* FIXME: should use BER library */
+       if( ( ctrl->ldctl_value.bv_len != 3 )
+               && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
+               && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
+       {
+               *text = "subentries control value encoding is bogus";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       op->o_subentries = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
+
+       return LDAP_SUCCESS;
+}
+#endif
+
+#ifdef LDAP_CONTROL_PERMITMODIFY
+static int parsePermitModify (
+       Connection *conn,
+       Operation *op,
+       LDAPControl *ctrl,
+       const char **text )
+{
+       if ( op->o_permitmodify != SLAP_NO_CONTROL ) {
+               *text = "permitmodify control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_value.bv_len ) {
+               *text = "permitmodify control value not empty";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       op->o_permitmodify = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       return LDAP_SUCCESS;
+}
+#endif
+
+#ifdef LDAP_CONTROL_NOREFERRALS
+static int parseNoReferrals (
+       Connection *conn,
+       Operation *op,
+       LDAPControl *ctrl,
+       const char **text )
+{
+       if ( op->o_noreferrals != SLAP_NO_CONTROL ) {
+               *text = "noreferrals control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_value.bv_len ) {
+               *text = "noreferrals control value not empty";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       op->o_noreferrals = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       return LDAP_SUCCESS;
+}
 #endif
 
 #ifdef LDAP_CLIENT_UPDATE
@@ -651,8 +883,15 @@ static int parseClientUpdate (
                return LDAP_PROTOCOL_ERROR;
        }
 
+#ifdef LDAP_SYNC
+       if ( op->o_sync != SLAP_NO_CONTROL ) {
+               *text = "LDAP Client Update and Sync controls used together";
+               return LDAP_PROTOCOL_ERROR;
+       }
+#endif
+
        if ( ctrl->ldctl_value.bv_len == 0 ) {
-               *text = "LCUP client update control value is empty";
+               *text = "LCUP client update control value is empty (or absent)";
                return LDAP_PROTOCOL_ERROR;
        }
 
@@ -719,7 +958,7 @@ static int parseClientUpdate (
                return LDAP_PROTOCOL_ERROR;
        }
 
-       if ( tag == LDAP_TAG_COOKIE ) {
+       if ( tag == LDAP_LCUP_TAG_COOKIE ) {
                if ( (tag = ber_scanf( ber, /*{*/ "{mm}}",
                                        &scheme, &cookie )) == LBER_ERROR ) {
                        *text = "LCUP client update control : decoding error";
@@ -753,4 +992,113 @@ static int parseClientUpdate (
 
        return LDAP_SUCCESS;
 }
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+
+#ifdef LDAP_SYNC
+static int parseLdupSync (
+       Connection *conn,
+       Operation *op,
+       LDAPControl *ctrl,
+       const char **text )
+{
+       ber_tag_t tag;
+       BerElement *ber;
+       ber_int_t mode;
+       ber_len_t len;
+       struct berval cookie = { 0, NULL };
+
+       if ( op->o_sync != SLAP_NO_CONTROL ) {
+               *text = "LDAP Sync control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+#ifdef LDAP_CLIENT_UPDATE
+       if ( op->o_clientupdate != SLAP_NO_CONTROL ) {
+               *text = "LDAP Sync and LDAP Client Update controls used together";
+               return LDAP_PROTOCOL_ERROR;
+       }
+#endif
+
+       if ( ctrl->ldctl_value.bv_len == 0 ) {
+               *text = "LDAP Sync control value is empty (or absent)";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       /* Parse the control value
+        *      syncRequestValue ::= SEQUENCE {
+        *              mode   ENUMERATED {
+        *                      -- 0 unused
+        *                      refreshOnly             (1),
+        *                      -- 2 reserved
+        *                      refreshAndPersist       (3)
+        *              },
+        *              cookie  syncCookie OPTIONAL
+        *      }
+        */
+
+       ber = ber_init( &ctrl->ldctl_value );
+       if( ber == NULL ) {
+               *text = "internal error";
+               return LDAP_OTHER;
+       }
+
+       if ( (tag = ber_scanf( ber, "{i" /*}*/, &mode )) == LBER_ERROR ) {
+               *text = "LDAP Sync control : mode decoding error";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       switch( mode ) {
+       case LDAP_SYNC_REFRESH_ONLY:
+               mode = SLAP_SYNC_REFRESH;
+               break;
+       case LDAP_SYNC_REFRESH_AND_PERSIST:
+               mode = SLAP_SYNC_REFRESH_AND_PERSIST;
+               break;
+       default:
+               *text = "LDAP Sync control : unknown update mode";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       tag = ber_peek_tag( ber, &len );
+
+       if ( tag == LDAP_SYNC_TAG_COOKIE ) {
+               if (( ber_scanf( ber, /*{*/ "m}",
+                                       &cookie )) == LBER_ERROR ) {
+                       *text = "LDAP Sync control : cookie decoding error";
+                       return LDAP_PROTOCOL_ERROR;
+               }
+       } else {
+               if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) {
+                       *text = "LDAP Sync control : decoding error";
+                       return LDAP_PROTOCOL_ERROR;
+               }
+               cookie.bv_len = 0;
+               cookie.bv_val = NULL;
+       }
+
+       /* TODO : Cookie Scheme Validation */
+#if 0
+       if ( lcup_cookie_scheme_validate(scheme) != LDAP_SUCCESS ) {
+               *text = "Unsupported LCUP cookie scheme";
+               return LCUP_UNSUPPORTED_SCHEME;
+       }
+
+       if ( lcup_cookie_validate(scheme, cookie) != LDAP_SUCCESS ) {
+               *text = "Invalid LCUP cookie";
+               return LCUP_INVALID_COOKIE;
+       }
+#endif
+
+       ber_dupbv( &op->o_sync_state, &cookie );
+
+       (void) ber_free( ber, 1 );
+
+       op->o_sync_mode = (char) mode;
+
+       op->o_sync = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       return LDAP_SUCCESS;
+}
+#endif
index cef1279c435f15ddb6b9af439ecd188c741a2a12..1db37ee4fbe229d28cca094dcfd4808fab89cec5 100644 (file)
@@ -1,7 +1,7 @@
 /* cr.c - content rule routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -24,13 +24,16 @@ struct cindexrec {
 };
 
 static Avlnode *cr_index = NULL;
-static ContentRule *cr_list = NULL;
+static LDAP_SLIST_HEAD(CRList, slap_content_rule) cr_list
+       = LDAP_SLIST_HEAD_INITIALIZER(&cr_list);
 
 static int
 cr_index_cmp(
-    struct cindexrec   *cir1,
-    struct cindexrec   *cir2 )
+    const void *v_cir1,
+    const void *v_cir2 )
 {
+       const struct cindexrec  *cir1 = v_cir1;
+       const struct cindexrec  *cir2 = v_cir2;
        int i = cir1->cir_name.bv_len - cir2->cir_name.bv_len;
        if (i)
                return i;
@@ -39,9 +42,11 @@ cr_index_cmp(
 
 static int
 cr_index_name_cmp(
-    struct berval      *name,
-    struct cindexrec   *cir )
+    const void *v_name,
+    const void *v_cir )
 {
+       const struct berval    *name = v_name;
+       const struct cindexrec *cir  = v_cir;
        int i = name->bv_len - cir->cir_name.bv_len;
        if (i)
                return i;
@@ -64,8 +69,7 @@ cr_bvfind( struct berval *crname )
 {
        struct cindexrec        *cir;
 
-       cir = (struct cindexrec *) avl_find( cr_index, crname,
-            (AVL_CMP) cr_index_name_cmp );
+       cir = avl_find( cr_index, crname, cr_index_name_cmp );
 
        if ( cir != NULL ) {
                return( cir->cir_cr );
@@ -74,20 +78,32 @@ cr_bvfind( struct berval *crname )
        return( NULL );
 }
 
+static int
+cr_destroy_one( ContentRule *c )
+{
+       assert( c != NULL );
+
+       if (c->scr_auxiliaries) ldap_memfree(c->scr_auxiliaries);
+       if (c->scr_required) ldap_memfree(c->scr_required);
+       if (c->scr_allowed) ldap_memfree(c->scr_allowed);
+       if (c->scr_precluded) ldap_memfree(c->scr_precluded);
+       ldap_contentrule_free((LDAPContentRule *)c);
+
+       return 0;
+}
+
 void
 cr_destroy( void )
 {
-       ContentRule *c, *n;
+       ContentRule *c;
 
        avl_free(cr_index, ldap_memfree);
-       for (c=cr_list; c; c=n)
-       {
-               n = c->scr_next;
-               if (c->scr_auxiliaries) ldap_memfree(c->scr_auxiliaries);
-               if (c->scr_required) ldap_memfree(c->scr_required);
-               if (c->scr_allowed) ldap_memfree(c->scr_allowed);
-               if (c->scr_precluded) ldap_memfree(c->scr_precluded);
-               ldap_contentrule_free((LDAPContentRule *)c);
+
+       while( !LDAP_SLIST_EMPTY(&cr_list) ) {
+               c = LDAP_SLIST_FIRST(&cr_list);
+               LDAP_SLIST_REMOVE_HEAD(&cr_list, scr_next);
+
+               cr_destroy_one( c );
        }
 }
 
@@ -97,15 +113,10 @@ cr_insert(
     const char         **err
 )
 {
-       ContentRule     **crp;
        struct cindexrec        *cir;
        char                    **names;
 
-       crp = &cr_list;
-       while ( *crp != NULL ) {
-               crp = &(*crp)->scr_next;
-       }
-       *crp = scr;
+       LDAP_SLIST_INSERT_HEAD(&cr_list, scr, scr_next);
 
        if ( scr->scr_oid ) {
                cir = (struct cindexrec *)
@@ -118,8 +129,7 @@ cr_insert(
                assert( cir->cir_cr );
 
                if ( avl_insert( &cr_index, (caddr_t) cir,
-                                (AVL_CMP) cr_index_cmp,
-                                (AVL_DUP) avl_dup_error ) )
+                                cr_index_cmp, avl_dup_error ) )
                {
                        *err = scr->scr_oid;
                        ldap_memfree(cir);
@@ -142,8 +152,7 @@ cr_insert(
                        assert( cir->cir_cr );
 
                        if ( avl_insert( &cr_index, (caddr_t) cir,
-                                        (AVL_CMP) cr_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) )
+                                        cr_index_cmp, avl_dup_error ) )
                        {
                                *err = *names;
                                ldap_memfree(cir);
@@ -396,7 +405,7 @@ cr_schema_info( Entry *e )
 
        vals[1].bv_val = NULL;
 
-       for ( cr = cr_list; cr; cr = cr->scr_next ) {
+       LDAP_SLIST_FOREACH(cr, &cr_list, scr_next) {
                if ( ldap_contentrule2bv( &cr->scr_crule, vals ) == NULL ) {
                        return -1;
                }
index 7b0c6d7b117705a6443384cbc748496dfc09fdac..d4d42e3492716e529829833dfcc7344b38098a13 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -663,9 +663,6 @@ static int slap_open_listener(
                return -1;
 #endif
        } else {
-#ifdef LDAP_CONNECTIONLESS
-               l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
-#endif
                if( lud->lud_host == NULL || lud->lud_host[0] == '\0'
                        || strcmp(lud->lud_host, "*") == 0 )
                {
@@ -674,6 +671,9 @@ static int slap_open_listener(
                        err = slap_get_listener_addresses(lud->lud_host, port, &sal);
                }
        }
+#ifdef LDAP_CONNECTIONLESS
+       l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
+#endif
 
 #if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
        if ( lud->lud_exts ) {
@@ -1203,9 +1203,6 @@ slapd_daemon_task(
                fd_set                  writefds;
                Sockaddr                from;
 
-#if defined(SLAPD_RLOOKUPS)
-               struct hostent          *hp;
-#endif
                struct timeval          zero;
                struct timeval          *tvp;
 
@@ -1558,6 +1555,19 @@ slapd_daemon_task(
                        case AF_LOCAL:
                                sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
                                ssf = LDAP_PVT_SASL_LOCAL_SSF;
+                               {
+                                       uid_t uid;
+                                       gid_t gid;
+
+                                       if( getpeereid( s, &uid, &gid ) == 0 ) {
+                                               authid = ch_malloc(
+                                                       sizeof("uidNumber=4294967295+gidNumber=4294967295,"
+                                                               "cn=peercred,cn=external,cn=auth"));
+                                               sprintf(authid, "uidNumber=%d+gidNumber=%d,"
+                                                       "cn=peercred,cn=external,cn=auth",
+                                                       (int) uid, (int) gid);
+                                       }
+                               }
                                dnsname = "local";
                                break;
 #endif /* LDAP_PF_LOCAL */
@@ -1681,8 +1691,7 @@ slapd_daemon_task(
                        }
 
                        Statslog( LDAP_DEBUG_STATS,
-                               "conn=%ld fd=%ld ACCEPT from %s "
-                               "(%s)\n",
+                               "conn=%ld fd=%ld ACCEPT from %s (%s)\n",
                                id, (long) s,
                                peername,
                                slap_listeners[l]->sl_name.bv_val,
index 97f073e1b9c4e0aceec34ba0283252949f192a22..9ac507a65a7a8c4f33d7f5e842fae56e0f5985ec 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -24,6 +24,9 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 
 int
 do_delete(
@@ -39,6 +42,10 @@ do_delete(
        int rc;
        int manageDSAit;
 
+#ifdef LDAP_SLAPI
+       Slapi_PBlock *pb = op->o_pb;
+#endif
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, 
                "do_delete: conn %d\n", conn->c_connid, 0, 0 );
@@ -153,6 +160,32 @@ do_delete(
        /* deref suffix alias if appropriate */
        suffix_alias( be, &ndn );
 
+#if defined( LDAP_SLAPI )
+       slapi_x_backend_set_pb( pb, be );
+       slapi_x_connection_set_pb( pb, conn );
+       slapi_x_operation_set_pb( pb, op );
+       slapi_pblock_set( pb, SLAPI_DELETE_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_DELETE_FN, pb );
+       if ( rc != 0 ) {
+               /*
+                * A preoperation plugin failure will abort the
+                * entire operation.
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_delete: delete preoperation plugin "
+                               "failed\n", 0, 0, 0 );
+#else
+               Debug (LDAP_DEBUG_TRACE, "do_delete: delete preoperation plugin failed.\n",
+                               0, 0, 0);
+#endif
+               if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0 )
+                       rc = LDAP_OTHER;
+               goto cleanup;
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        /*
         * do the delete if 1 && (2 || 3)
         * 1) there is a delete function implemented in this backend;
@@ -193,6 +226,18 @@ do_delete(
                        NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       if ( doPluginFNs( be, SLAPI_PLUGIN_POST_DELETE_FN, pb ) != 0) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_delete: delete postoperation plugins "
+                               "failed\n", 0, 0, 0 );
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_delete: delete postoperation plugins "
+                               "failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        free( pdn.bv_val );
        free( ndn.bv_val );
index b07ad02b4327eb73e0aa5e43109e1757d5fc864b..40f29db621a74b144613f72a5dac7507c59d9ddc 100644 (file)
@@ -1,7 +1,7 @@
 /* entry.c - routines for dealing with entries */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -388,17 +388,19 @@ entry_cmp( Entry *e1, Entry *e2 )
 }
 
 int
-entry_dn_cmp( Entry *e1, Entry *e2 )
+entry_dn_cmp( const void *v_e1, const void *v_e2 )
 {
        /* compare their normalized UPPERCASED dn's */
+       const Entry *e1 = v_e1, *e2 = v_e2;
        int rc = e1->e_nname.bv_len - e2->e_nname.bv_len;
        if (rc) return rc;
        return( strcmp( e1->e_ndn, e2->e_ndn ) );
 }
 
 int
-entry_id_cmp( Entry *e1, Entry *e2 )
+entry_id_cmp( const void *v_e1, const void *v_e2 )
 {
+       const Entry *e1 = v_e1, *e2 = v_e2;
        return( e1->e_id < e2->e_id ? -1 : (e1->e_id > e2->e_id ? 1 : 0) );
 }
 
index 0da22bdfbbfdc46db73a3fb9282832524ba66a81..4e8c7d1eb483b7a7b16191407a3fb91c4206659b 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /* 
- * Copyright 1999-2002 The OpenLDAP Foundation.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #include "portable.h"
 
 #include <stdio.h>
+
 #include <ac/socket.h>
 #include <ac/string.h>
 
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 #include "lber_pvt.h"
 
+#define UNSUPPORTED_EXTENDEDOP "unsupported extended operation"
+
 static struct extop_list {
        struct extop_list *next;
        struct berval oid;
@@ -55,11 +61,14 @@ static struct {
        struct berval oid;
        SLAP_EXTOP_MAIN_FN *ext_main;
 } builtin_extops[] = {
+       { BVC(LDAP_EXOP_X_WHO_AM_I), whoami_extop },
+       { BVC(LDAP_EXOP_MODIFY_PASSWD), passwd_extop },
+#ifdef LDAP_EXOP_X_CANCEL
+       { BVC(LDAP_EXOP_X_CANCEL), cancel_extop },
+#endif
 #ifdef HAVE_TLS
        { BVC(LDAP_EXOP_START_TLS), starttls_extop },
 #endif
-       { BVC(LDAP_EXOP_MODIFY_PASSWD), passwd_extop },
-       { BVC(LDAP_EXOP_X_WHO_AM_I), whoami_extop },
        { {0,NULL}, NULL }
 };
 
@@ -102,6 +111,14 @@ do_extended(
        struct berval *rspdata;
        LDAPControl **rspctrls;
 
+#if defined(LDAP_SLAPI) 
+       Slapi_PBlock    *pb = op->o_pb;
+       SLAPI_FUNC      funcAddr = NULL;
+       int             extop_rc;
+       int             msg_sent = FALSE;
+       char            *result_msg = "";
+#endif /* defined(LDAP_SLAPI) */
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_extended: conn %d\n", conn->c_connid, 0, 0 );
 #else
@@ -136,7 +153,16 @@ do_extended(
                goto done;
        }
 
-       if( !(ext = find_extop(supp_ext_list, &reqoid)) ) {
+       if( !(ext = find_extop(supp_ext_list, &reqoid))
+#ifdef LDAP_SLAPI
+               && !(funcAddr)
+#endif
+       ) {
+#ifdef LDAP_SLAPI
+               /* Netscape extended operation */
+               getPluginFunc( &reqoid, &funcAddr );
+#endif
+
 #ifdef NEW_LOGGING
                LDAP_LOG( OPERATION, ERR, 
                        "do_extended: conn %d  unsupported operation \"%s\"\n",
@@ -150,6 +176,8 @@ do_extended(
                goto done;
        }
 
+       op->o_extendedop = reqoid.bv_val;
+
        tag = ber_peek_tag( op->o_ber, &len );
        
        if( ber_peek_tag( op->o_ber, &len ) == LDAP_TAG_EXOP_REQ_VALUE ) {
@@ -200,29 +228,106 @@ do_extended(
        text = NULL;
        refs = NULL;
 
-       rc = (ext->ext_main)( conn, op,
-               reqoid.bv_val, reqdata.bv_val ? &reqdata : NULL,
-               &rspoid, &rspdata, &rspctrls, &text, &refs );
+#if defined(LDAP_SLAPI)
+       if (ext != NULL) { /* OpenLDAP extended operation */
+#endif /* defined(LDAP_SLAPI) */
+
+               rc = (ext->ext_main)( conn, op,
+                         reqoid.bv_val, reqdata.bv_val ? &reqdata : NULL,
+                         &rspoid, &rspdata, &rspctrls, &text, &refs );
+
+               if( rc != SLAPD_ABANDON ) {
+                       if ( rc == LDAP_REFERRAL && refs == NULL ) {
+                               refs = referral_rewrite( default_referral,
+                                       NULL, NULL, LDAP_SCOPE_DEFAULT );
+                       }
+
+                       send_ldap_extended( conn, op, rc, NULL, text, refs,
+                               rspoid, rspdata, rspctrls );
 
-       if( rc != SLAPD_ABANDON ) {
-               if ( rc == LDAP_REFERRAL && refs == NULL ) {
-                       refs = referral_rewrite( default_referral,
-                               NULL, NULL, LDAP_SCOPE_DEFAULT );
+                       ber_bvarray_free( refs );
                }
 
-               send_ldap_extended( conn, op, rc, NULL, text, refs,
-                       rspoid, rspdata, rspctrls );
+               if ( rspoid != NULL ) {
+                       free( rspoid );
+               }
 
-               ber_bvarray_free( refs );
-       }
+               if ( rspdata != NULL ) {
+                       ber_bvfree( rspdata );
+               }
 
-       if ( rspoid != NULL ) {
-               free( rspoid );
-       }
+#if defined( LDAP_SLAPI )
+               goto done;  /* end of OpenLDAP extended operation */
 
-       if ( rspdata != NULL ) {
-               ber_bvfree( rspdata );
-       }
+       } else { /* start of Netscape extended operation */
+               rc = slapi_pblock_set( pb, SLAPI_EXT_OP_REQ_OID,
+                               (void *)reqoid.bv_val);
+               if ( rc != LDAP_SUCCESS ) {
+                       rc = LDAP_OTHER;
+                       goto done;
+               }
+
+               rc = slapi_pblock_set( pb, SLAPI_EXT_OP_REQ_VALUE,
+                               (void *)&reqdata);
+               if ( rc != LDAP_SUCCESS ) {
+                       rc = LDAP_OTHER;
+                       goto done;
+               }
+
+               rc = slapi_x_connection_set_pb( pb, conn );
+               if ( rc != LDAP_SUCCESS ) {
+                       rc = LDAP_OTHER;
+                       goto done;
+               }
+
+               rc = slapi_x_operation_set_pb( pb, op );
+               if ( rc != LDAP_SUCCESS ) {
+                       rc = LDAP_OTHER;
+                       goto done;
+               }
+
+               extop_rc = (*funcAddr)( pb );
+               if ( extop_rc == SLAPI_PLUGIN_EXTENDED_SENT_RESULT ) {
+                       msg_sent = TRUE;
+
+               } else if ( extop_rc == SLAPI_PLUGIN_EXTENDED_NOT_HANDLED ) {
+                       rc = LDAP_PROTOCOL_ERROR;
+                       result_msg = UNSUPPORTED_EXTENDEDOP;
+
+               } else {
+                       rc = slapi_pblock_get( pb, SLAPI_EXT_OP_RET_OID,
+                                       &rspoid);
+                       if ( rc != LDAP_SUCCESS ) {
+                               goto done2;
+                       }
+
+                       rc = slapi_pblock_get( pb, SLAPI_EXT_OP_RET_VALUE,
+                                       &rspdata);
+                       if ( rc != LDAP_SUCCESS ) {
+                               goto done2;
+                       }
+
+                       send_ldap_extended( conn, op, extop_rc, NULL, text,
+                                       refs, rspoid, rspdata, rspctrls );
+                       msg_sent = TRUE;
+               }
+
+done2:;
+               if ( rc != LDAP_SUCCESS && msg_sent == FALSE ) {
+                       send_ldap_result( conn, op, rc, NULL, result_msg,
+                                       NULL, NULL );
+               }
+
+               if ( rspoid != NULL ) {
+                       free( rspoid );
+               }
+
+               if ( rspdata != NULL ) {
+                       ber_bvfree( rspdata );
+               }
+
+       } /* end of Netscape extended operation */
+#endif /* defined( LDAP_SLAPI ) */
 
 done:
        return rc;
index 63975090bcad9e121b695033a9048b44e14ba4cf..45a8d190e9b343bb9488670d3cb149dd4ab92356 100644 (file)
@@ -1,7 +1,7 @@
 /* filter.c - routines for parsing and dealing with filters */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -822,7 +822,7 @@ get_simple_vrFilter(
        ber_tag_t       tag;
        ber_len_t       len;
        int             err;
-       ValuesReturnFilter *f;
+       ValuesReturnFilter *vrf;
 
 #ifdef NEW_LOGGING
        LDAP_LOG( FILTER, ENTRY, 
@@ -838,13 +838,13 @@ get_simple_vrFilter(
                return SLAPD_DISCONNECT;
        }
 
-       f = (ValuesReturnFilter *) ch_malloc( sizeof(ValuesReturnFilter) );
-       f->f_next = NULL;
+       vrf = (ValuesReturnFilter *) ch_malloc( sizeof(ValuesReturnFilter) );
+       vrf->vrf_next = NULL;
 
        err = LDAP_SUCCESS;
-       f->f_choice = tag; 
+       vrf->vrf_choice = tag; 
 
-       switch ( f->f_choice ) {
+       switch ( vrf->vrf_choice ) {
        case LDAP_FILTER_EQUALITY:
 #ifdef NEW_LOGGING
                LDAP_LOG( FILTER, DETAIL2, 
@@ -852,12 +852,12 @@ get_simple_vrFilter(
 #else
                Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
 #endif
-               err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY, text );
+               err = get_ava( ber, &vrf->vrf_ava, SLAP_MR_EQUALITY, text );
                if ( err != LDAP_SUCCESS ) {
                        break;
                }
 
-               assert( f->f_ava != NULL );
+               assert( vrf->vrf_ava != NULL );
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
@@ -867,7 +867,7 @@ get_simple_vrFilter(
 #else
                Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
 #endif
-               err = get_substring_filter( conn, ber, (Filter *)f, text );
+               err = get_substring_filter( conn, ber, (Filter *)vrf, text );
                break;
 
        case LDAP_FILTER_GE:
@@ -877,7 +877,7 @@ get_simple_vrFilter(
 #else
                Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
 #endif
-               err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
+               err = get_ava( ber, &vrf->vrf_ava, SLAP_MR_ORDERING, text );
                if ( err != LDAP_SUCCESS ) {
                        break;
                }
@@ -890,7 +890,7 @@ get_simple_vrFilter(
 #else
                Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
 #endif
-               err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
+               err = get_ava( ber, &vrf->vrf_ava, SLAP_MR_ORDERING, text );
                if ( err != LDAP_SUCCESS ) {
                        break;
                }
@@ -911,13 +911,13 @@ get_simple_vrFilter(
                        break;
                }
 
-               f->f_desc = NULL;
-               err = slap_bv2ad( &type, &f->f_desc, text );
+               vrf->vrf_desc = NULL;
+               err = slap_bv2ad( &type, &vrf->vrf_desc, text );
 
                if( err != LDAP_SUCCESS ) {
                        /* unrecognized attribute description or other error */
-                       f->f_choice = SLAPD_FILTER_COMPUTED;
-                       f->f_result = LDAP_COMPARE_FALSE;
+                       vrf->vrf_choice = SLAPD_FILTER_COMPUTED;
+                       vrf->vrf_result = LDAP_COMPARE_FALSE;
                        err = LDAP_SUCCESS;
                        break;
                }
@@ -930,7 +930,7 @@ get_simple_vrFilter(
 #else
                Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
 #endif
-               err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY_APPROX, text );
+               err = get_ava( ber, &vrf->vrf_ava, SLAP_MR_EQUALITY_APPROX, text );
                if ( err != LDAP_SUCCESS ) {
                        break;
                }
@@ -944,12 +944,12 @@ get_simple_vrFilter(
                Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 );
 #endif
 
-               err = get_mra( ber, &f->f_mra, text );
+               err = get_mra( ber, &vrf->vrf_mra, text );
                if ( err != LDAP_SUCCESS ) {
                        break;
                }
 
-               assert( f->f_mra != NULL );
+               assert( vrf->vrf_mra != NULL );
                break;
 
        default:
@@ -957,30 +957,30 @@ get_simple_vrFilter(
 #ifdef NEW_LOGGING
                LDAP_LOG( FILTER, ERR, 
                        "get_simple_vrFilter: conn %d unknown filter type=%lu\n",
-                       conn->c_connid, f->f_choice, 0 );
+                       conn->c_connid, vrf->vrf_choice, 0 );
 #else
                Debug( LDAP_DEBUG_ANY, "get_simple_vrFilter: unknown filter type=%lu\n",
-                       f->f_choice, 0, 0 );
+                       vrf->vrf_choice, 0, 0 );
 #endif
-               f->f_choice = SLAPD_FILTER_COMPUTED;
-               f->f_result = SLAPD_COMPARE_UNDEFINED;
+               vrf->vrf_choice = SLAPD_FILTER_COMPUTED;
+               vrf->vrf_result = SLAPD_COMPARE_UNDEFINED;
                break;
        }
 
        if ( err != LDAP_SUCCESS ) {
                if( err != SLAPD_DISCONNECT ) {
                        /* ignore error */
-                       f->f_choice = SLAPD_FILTER_COMPUTED;
-                       f->f_result = SLAPD_COMPARE_UNDEFINED;
+                       vrf->vrf_choice = SLAPD_FILTER_COMPUTED;
+                       vrf->vrf_result = SLAPD_COMPARE_UNDEFINED;
                        err = LDAP_SUCCESS;
-                       *filt = f;
+                       *filt = vrf;
 
                } else {
-                       free(f);
+                       free(vrf);
                }
 
        } else {
-               *filt = f;
+               *filt = vrf;
        }
 
 #ifdef NEW_LOGGING
@@ -994,7 +994,7 @@ get_simple_vrFilter(
 
 int
 get_vrFilter( Connection *conn, BerElement *ber,
-       ValuesReturnFilter **f,
+       ValuesReturnFilter **vrf,
        const char **text )
 {
        /*
@@ -1026,7 +1026,7 @@ get_vrFilter( Connection *conn, BerElement *ber,
         *              matchValue      [3] AssertionValue }
         */
 
-       ValuesReturnFilter **new;
+       ValuesReturnFilter **n;
        ber_tag_t       tag;
        ber_len_t       len;
        char            *last;
@@ -1050,16 +1050,17 @@ get_vrFilter( Connection *conn, BerElement *ber,
                return SLAPD_DISCONNECT;
        }
 
-       new = f;
-       for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
+       n = vrf;
+       for ( tag = ber_first_element( ber, &len, &last );
+               tag != LBER_DEFAULT;
                tag = ber_next_element( ber, &len, last ) )
        {
-               int err = get_simple_vrFilter( conn, ber, new, text );
+               int err = get_simple_vrFilter( conn, ber, n, text );
                if ( err != LDAP_SUCCESS )
                        return( err );
-               new = &(*new)->f_next;
+               n = &(*n)->vrf_next;
        }
-       *new = NULL;
+       *n = NULL;
 
 #ifdef NEW_LOGGING
        LDAP_LOG( FILTER, ENTRY, 
@@ -1071,18 +1072,18 @@ get_vrFilter( Connection *conn, BerElement *ber,
 }
 
 void
-vrFilter_free( ValuesReturnFilter *f )
+vrFilter_free( ValuesReturnFilter *vrf )
 {
        ValuesReturnFilter      *p, *next;
 
-       if ( f == NULL ) {
+       if ( vrf == NULL ) {
                return;
        }
 
-       for ( p = f; p != NULL; p = next ) {
-               next = p->f_next;
+       for ( p = vrf; p != NULL; p = next ) {
+               next = p->vrf_next;
 
-               switch ( f->f_choice ) {
+               switch ( vrf->vrf_choice ) {
                case LDAP_FILTER_PRESENT:
                        break;
 
@@ -1090,22 +1091,22 @@ vrFilter_free( ValuesReturnFilter *f )
                case LDAP_FILTER_GE:
                case LDAP_FILTER_LE:
                case LDAP_FILTER_APPROX:
-                       ava_free( f->f_ava, 1 );
+                       ava_free( vrf->vrf_ava, 1 );
                        break;
 
                case LDAP_FILTER_SUBSTRINGS:
-                       if ( f->f_sub_initial.bv_val != NULL ) {
-                               free( f->f_sub_initial.bv_val );
+                       if ( vrf->vrf_sub_initial.bv_val != NULL ) {
+                               free( vrf->vrf_sub_initial.bv_val );
                        }
-                       ber_bvarray_free( f->f_sub_any );
-                       if ( f->f_sub_final.bv_val != NULL ) {
-                               free( f->f_sub_final.bv_val );
+                       ber_bvarray_free( vrf->vrf_sub_any );
+                       if ( vrf->vrf_sub_final.bv_val != NULL ) {
+                               free( vrf->vrf_sub_final.bv_val );
                        }
-                       ch_free( f->f_sub );
+                       ch_free( vrf->vrf_sub );
                        break;
 
                case LDAP_FILTER_EXT:
-                       mra_free( f->f_mra, 1 );
+                       mra_free( vrf->vrf_mra, 1 );
                        break;
 
                case SLAPD_FILTER_COMPUTED:
@@ -1114,27 +1115,27 @@ vrFilter_free( ValuesReturnFilter *f )
                default:
 #ifdef NEW_LOGGING
                        LDAP_LOG( FILTER, ERR, 
-                               "filter_free: unknown filter type %lu\n", f->f_choice, 0, 0 );
+                               "filter_free: unknown filter type %lu\n", vrf->vrf_choice, 0, 0 );
 #else
                        Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
-                               f->f_choice, 0, 0 );
+                               vrf->vrf_choice, 0, 0 );
 #endif
                        break;
                }
 
-               free( f );
+               free( vrf );
        }
 }
 
 
 void
-vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
+vrFilter2bv( ValuesReturnFilter *vrf, struct berval *fstr )
 {
        ValuesReturnFilter      *p;
        struct berval tmp;
        ber_len_t len;
 
-       if ( f == NULL ) {
+       if ( vrf == NULL ) {
                ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
                return;
        }
@@ -1144,7 +1145,7 @@ vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
 
        snprintf( fstr->bv_val, fstr->bv_len + 1, "()");
 
-       for ( p = f; p != NULL; p = p->f_next ) {
+       for ( p = vrf; p != NULL; p = p->vrf_next ) {
                len = fstr->bv_len;
 
                simple_vrFilter2bv( p, &tmp );
@@ -1160,84 +1161,84 @@ vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
 }
 
 static void
-simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
+simple_vrFilter2bv( ValuesReturnFilter *vrf, struct berval *fstr )
 {
        struct berval tmp;
        ber_len_t len;
 
-       if ( f == NULL ) {
+       if ( vrf == NULL ) {
                ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
                return;
        }
 
-       switch ( f->f_choice ) {
+       switch ( vrf->vrf_choice ) {
        case LDAP_FILTER_EQUALITY:
-               filter_escape_value( &f->f_av_value, &tmp );
+               filter_escape_value( &vrf->vrf_av_value, &tmp );
 
-               fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
+               fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
                        tmp.bv_len + ( sizeof("(=)") - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
-                       f->f_av_desc->ad_cname.bv_val,
+                       vrf->vrf_av_desc->ad_cname.bv_val,
                        tmp.bv_val );
 
                ber_memfree( tmp.bv_val );
                break;
 
        case LDAP_FILTER_GE:
-               filter_escape_value( &f->f_av_value, &tmp );
+               filter_escape_value( &vrf->vrf_av_value, &tmp );
 
-               fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
+               fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
                        tmp.bv_len + ( sizeof("(>=)") - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
-                       f->f_av_desc->ad_cname.bv_val,
+                       vrf->vrf_av_desc->ad_cname.bv_val,
                        tmp.bv_val );
 
                ber_memfree( tmp.bv_val );
                break;
 
        case LDAP_FILTER_LE:
-               filter_escape_value( &f->f_av_value, &tmp );
+               filter_escape_value( &vrf->vrf_av_value, &tmp );
 
-               fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
+               fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
                        tmp.bv_len + ( sizeof("(<=)") - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
-                       f->f_av_desc->ad_cname.bv_val,
+                       vrf->vrf_av_desc->ad_cname.bv_val,
                        tmp.bv_val );
 
                ber_memfree( tmp.bv_val );
                break;
 
        case LDAP_FILTER_APPROX:
-               filter_escape_value( &f->f_av_value, &tmp );
+               filter_escape_value( &vrf->vrf_av_value, &tmp );
 
-               fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
+               fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
                        tmp.bv_len + ( sizeof("(~=)") - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
-                       f->f_av_desc->ad_cname.bv_val,
+                       vrf->vrf_av_desc->ad_cname.bv_val,
                        tmp.bv_val );
                ber_memfree( tmp.bv_val );
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
-               fstr->bv_len = f->f_sub_desc->ad_cname.bv_len +
+               fstr->bv_len = vrf->vrf_sub_desc->ad_cname.bv_len +
                        ( sizeof("(=*)") - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 128 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
-                       f->f_sub_desc->ad_cname.bv_val );
+                       vrf->vrf_sub_desc->ad_cname.bv_val );
 
-               if ( f->f_sub_initial.bv_val != NULL ) {
+               if ( vrf->vrf_sub_initial.bv_val != NULL ) {
                        len = fstr->bv_len;
 
-                       filter_escape_value( &f->f_sub_initial, &tmp );
+                       filter_escape_value( &vrf->vrf_sub_initial, &tmp );
 
                        fstr->bv_len += tmp.bv_len;
                        fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
@@ -1249,11 +1250,11 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
                        ber_memfree( tmp.bv_val );
                }
 
-               if ( f->f_sub_any != NULL ) {
+               if ( vrf->vrf_sub_any != NULL ) {
                        int i;
-                       for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
+                       for ( i = 0; vrf->vrf_sub_any[i].bv_val != NULL; i++ ) {
                                len = fstr->bv_len;
-                               filter_escape_value( &f->f_sub_any[i], &tmp );
+                               filter_escape_value( &vrf->vrf_sub_any[i], &tmp );
 
                                fstr->bv_len += tmp.bv_len + 1;
                                fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
@@ -1265,10 +1266,10 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
                        }
                }
 
-               if ( f->f_sub_final.bv_val != NULL ) {
+               if ( vrf->vrf_sub_final.bv_val != NULL ) {
                        len = fstr->bv_len;
 
-                       filter_escape_value( &f->f_sub_final, &tmp );
+                       filter_escape_value( &vrf->vrf_sub_final, &tmp );
 
                        fstr->bv_len += tmp.bv_len;
                        fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
@@ -1283,36 +1284,36 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
                break;
 
        case LDAP_FILTER_PRESENT:
-               fstr->bv_len = f->f_desc->ad_cname.bv_len +
+               fstr->bv_len = vrf->vrf_desc->ad_cname.bv_len +
                        ( sizeof("(=*)") - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
-                       f->f_desc->ad_cname.bv_val );
+                       vrf->vrf_desc->ad_cname.bv_val );
                break;
 
        case LDAP_FILTER_EXT: {
                struct berval ad;
-               filter_escape_value( &f->f_mr_value, &tmp );
+               filter_escape_value( &vrf->vrf_mr_value, &tmp );
 
-               if ( f->f_mr_desc ) {
-                       ad = f->f_mr_desc->ad_cname;
+               if ( vrf->vrf_mr_desc ) {
+                       ad = vrf->vrf_mr_desc->ad_cname;
                } else {
                        ad.bv_len = 0;
                        ad.bv_val = "";
                }
                        
                fstr->bv_len = ad.bv_len +
-                       ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
-                       ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
+                       ( vrf->vrf_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
+                       ( vrf->vrf_mr_rule_text.bv_len ? vrf->vrf_mr_rule_text.bv_len+1 : 0 ) +
                        tmp.bv_len + ( sizeof("(:=)") - 1 );
                fstr->bv_val = malloc( fstr->bv_len + 1 );
 
                snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
                        ad.bv_val,
-                       f->f_mr_dnattrs ? ":dn" : "",
-                       f->f_mr_rule_text.bv_len ? ":" : "",
-                       f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
+                       vrf->vrf_mr_dnattrs ? ":dn" : "",
+                       vrf->vrf_mr_rule_text.bv_len ? ":" : "",
+                       vrf->vrf_mr_rule_text.bv_len ? vrf->vrf_mr_rule_text.bv_val : "",
                        tmp.bv_val );
 
                ber_memfree( tmp.bv_val );
@@ -1320,13 +1321,13 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
 
        case SLAPD_FILTER_COMPUTED:
                ber_str2bv(
-                       f->f_result == LDAP_COMPARE_FALSE ? "(?=false)" :
-                       f->f_result == LDAP_COMPARE_TRUE ? "(?=true)" :
-                       f->f_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
+                       vrf->vrf_result == LDAP_COMPARE_FALSE ? "(?=false)" :
+                       vrf->vrf_result == LDAP_COMPARE_TRUE ? "(?=true)" :
+                       vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
                        "(?=error)",
-                       f->f_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
-                       f->f_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
-                       f->f_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
+                       vrf->vrf_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
+                       vrf->vrf_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
+                       vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
                        sizeof("(?=error)")-1,
                        1, fstr );
                break;
@@ -1341,7 +1342,7 @@ static int
 get_substring_vrFilter(
        Connection      *conn,
        BerElement      *ber,
-       ValuesReturnFilter      *f,
+       ValuesReturnFilter      *vrf,
        const char      **text )
 {
        ber_tag_t       tag;
@@ -1362,21 +1363,21 @@ get_substring_vrFilter(
                return SLAPD_DISCONNECT;
        }
 
-       f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
-       f->f_sub_desc = NULL;
-       rc = slap_bv2ad( &bv, &f->f_sub_desc, text );
+       vrf->vrf_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
+       vrf->vrf_sub_desc = NULL;
+       rc = slap_bv2ad( &bv, &vrf->vrf_sub_desc, text );
 
        if( rc != LDAP_SUCCESS ) {
                text = NULL;
-               ch_free( f->f_sub );
-               f->f_choice = SLAPD_FILTER_COMPUTED;
-               f->f_result = SLAPD_COMPARE_UNDEFINED;
+               ch_free( vrf->vrf_sub );
+               vrf->vrf_choice = SLAPD_FILTER_COMPUTED;
+               vrf->vrf_result = SLAPD_COMPARE_UNDEFINED;
                return LDAP_SUCCESS;
        }
 
-       f->f_sub_initial.bv_val = NULL;
-       f->f_sub_any = NULL;
-       f->f_sub_final.bv_val = NULL;
+       vrf->vrf_sub_initial.bv_val = NULL;
+       vrf->vrf_sub_any = NULL;
+       vrf->vrf_sub_final.bv_val = NULL;
 
        for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
                tag = ber_next_element( ber, &len, last ) )
@@ -1423,13 +1424,13 @@ get_substring_vrFilter(
                }
 
                /* valiate using equality matching rule validator! */
-               rc = value_validate( f->f_sub_desc->ad_type->sat_equality,
+               rc = value_validate( vrf->vrf_sub_desc->ad_type->sat_equality,
                        &value, text );
                if( rc != LDAP_SUCCESS ) {
                        goto return_error;
                }
 
-               rc = value_normalize( f->f_sub_desc, usage,
+               rc = value_normalize( vrf->vrf_sub_desc, usage,
                        &value, &bv, text );
                if( rc != LDAP_SUCCESS ) {
                        goto return_error;
@@ -1449,15 +1450,15 @@ get_substring_vrFilter(
                        Debug( LDAP_DEBUG_FILTER, "  INITIAL\n", 0, 0, 0 );
 #endif
 
-                       if ( f->f_sub_initial.bv_val != NULL
-                               || f->f_sub_any != NULL 
-                               || f->f_sub_final.bv_val != NULL )
+                       if ( vrf->vrf_sub_initial.bv_val != NULL
+                               || vrf->vrf_sub_any != NULL 
+                               || vrf->vrf_sub_final.bv_val != NULL )
                        {
                                free( value.bv_val );
                                goto return_error;
                        }
 
-                       f->f_sub_initial = value;
+                       vrf->vrf_sub_initial = value;
                        break;
 
                case LDAP_SUBSTRING_ANY:
@@ -1468,12 +1469,12 @@ get_substring_vrFilter(
                        Debug( LDAP_DEBUG_FILTER, "  ANY\n", 0, 0, 0 );
 #endif
 
-                       if ( f->f_sub_final.bv_val != NULL ) {
+                       if ( vrf->vrf_sub_final.bv_val != NULL ) {
                                free( value.bv_val );
                                goto return_error;
                        }
 
-                       ber_bvarray_add( &f->f_sub_any, &value );
+                       ber_bvarray_add( &vrf->vrf_sub_any, &value );
                        break;
 
                case LDAP_SUBSTRING_FINAL:
@@ -1484,12 +1485,12 @@ get_substring_vrFilter(
                        Debug( LDAP_DEBUG_FILTER, "  FINAL\n", 0, 0, 0 );
 #endif
 
-                       if ( f->f_sub_final.bv_val != NULL ) {
+                       if ( vrf->vrf_sub_final.bv_val != NULL ) {
                                free( value.bv_val );
                                goto return_error;
                        }
 
-                       f->f_sub_final = value;
+                       vrf->vrf_sub_final = value;
                        break;
 
                default:
@@ -1514,10 +1515,10 @@ return_error:
                        Debug( LDAP_DEBUG_FILTER, "  error=%ld\n",
                                (long) rc, 0, 0 );
 #endif
-                       free( f->f_sub_initial.bv_val );
-                       ber_bvarray_free( f->f_sub_any );
-                       free( f->f_sub_final.bv_val );
-                       ch_free( f->f_sub );
+                       free( vrf->vrf_sub_initial.bv_val );
+                       ber_bvarray_free( vrf->vrf_sub_any );
+                       free( vrf->vrf_sub_final.bv_val );
+                       ch_free( vrf->vrf_sub );
                        return rc;
                }
        }
index eee672a9b958d47df2b025abe7d2ac51d48f4c8c..f01e7a822b93c6dea6f7591cd6192cf95c15160e 100644 (file)
@@ -1,7 +1,7 @@
 /* filterentry.c - apply a filter to an entry */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -460,7 +460,6 @@ test_ava_filter(
                }
        }
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
        if ( ava->aa_desc == slap_schema.si_ad_hasSubordinates 
                        && be && be->be_has_subordinates ) {
                int             hasSubordinates;
@@ -493,7 +492,6 @@ test_ava_filter(
 
                return LDAP_COMPARE_FALSE;
        }
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
        return( LDAP_COMPARE_FALSE );
 }
@@ -517,7 +515,6 @@ test_presence_filter(
 
        a = attrs_find( e->e_attrs, desc );
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
        if ( a == NULL && desc == slap_schema.si_ad_hasSubordinates ) {
 
                /*
@@ -532,7 +529,6 @@ test_presence_filter(
 
                return LDAP_COMPARE_FALSE;
        }
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
        return a != NULL ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
 }
diff --git a/servers/slapd/index.c b/servers/slapd/index.c
new file mode 100644 (file)
index 0000000..4ee3519
--- /dev/null
@@ -0,0 +1,42 @@
+/* index.c - index utilities */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include "slap.h"
+
+int slap_str2index( const char *str, slap_mask_t *idx )
+{
+       if ( strcasecmp( str, "pres" ) == 0 ) {
+               *idx = SLAP_INDEX_PRESENT;
+       } else if ( strcasecmp( str, "eq" ) == 0 ) {
+               *idx = SLAP_INDEX_EQUALITY;
+       } else if ( strcasecmp( str, "approx" ) == 0 ) {
+               *idx = SLAP_INDEX_APPROX;
+       } else if ( strcasecmp( str, "subinitial" ) == 0 ) {
+               *idx = SLAP_INDEX_SUBSTR_INITIAL;
+       } else if ( strcasecmp( str, "subany" ) == 0 ) {
+               *idx = SLAP_INDEX_SUBSTR_ANY;
+       } else if ( strcasecmp( str, "subfinal" ) == 0 ) {
+               *idx = SLAP_INDEX_SUBSTR_FINAL;
+       } else if ( strcasecmp( str, "substr" ) == 0 ||
+               strcasecmp( str, "sub" ) == 0 )
+       {
+               *idx = SLAP_INDEX_SUBSTR_DEFAULT;
+       } else if ( strcasecmp( str, "nolang" ) == 0 || /* backwards compat */
+                   strcasecmp( str, "notags" ) == 0 ) {
+               *idx = SLAP_INDEX_NOTAGS;
+       } else if ( strcasecmp( str, "nosubtypes" ) == 0 ) {
+               *idx = SLAP_INDEX_NOSUBTYPES;
+       } else {
+               return LDAP_OTHER;
+       }
+
+       return LDAP_SUCCESS;
+}
index 90f66152ea85758efc344eaf96c4d0394d7d3259..a9031b6f6ba50ab118664daf682d9218faa9b304 100644 (file)
@@ -1,7 +1,7 @@
 /* init.c - initialize various things */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -71,65 +71,6 @@ ldap_pvt_thread_mutex_t      replog_mutex;
 static const char* slap_name = NULL;
 int slapMode = SLAP_UNDEFINED_MODE;
 
-/*
- * all known control OIDs should be added to this list
- */
-char *slap_known_controls[] = {
-#ifdef LDAP_CONTROL_REFERRALS
-       LDAP_CONTROL_REFERRALS,
-#endif /* LDAP_CONTROL_REFERRALS */
-
-#ifdef LDAP_CONTROL_MANAGEDSAIT
-       LDAP_CONTROL_MANAGEDSAIT,
-#endif /* LDAP_CONTROL_MANAGEDSAIT */
-
-#ifdef LDAP_CONTROL_SUBENTRIES
-       LDAP_CONTROL_SUBENTRIES,
-#endif /* LDAP_CONTROL_SUBENTRIES */
-
-#ifdef LDAP_CONTROL_NOOP
-       LDAP_CONTROL_NOOP,
-#endif /* LDAP_CONTROL_NOOP */
-
-#ifdef LDAP_CONTROL_DUPENT_REQUEST
-       LDAP_CONTROL_DUPENT_REQUEST,
-#endif /* LDAP_CONTROL_DUPENT_REQUEST */
-
-#ifdef LDAP_CONTROL_DUPENT_RESPONSE
-       LDAP_CONTROL_DUPENT_RESPONSE,
-#endif /* LDAP_CONTROL_DUPENT_RESPONSE */
-
-#ifdef LDAP_CONTROL_DUPENT_ENTRY
-       LDAP_CONTROL_DUPENT_ENTRY,
-#endif /* LDAP_CONTROL_DUPENT_ENTRY */
-
-#ifdef LDAP_CONTROL_PAGEDRESULTS
-       LDAP_CONTROL_PAGEDRESULTS,
-#endif /* LDAP_CONTROL_PAGEDRESULTS */
-
-#ifdef LDAP_CONTROL_SORTREQUEST
-       LDAP_CONTROL_SORTREQUEST,
-#endif /* LDAP_CONTROL_SORTREQUEST */
-
-#ifdef LDAP_CONTROL_SORTRESPONSE
-       LDAP_CONTROL_SORTRESPONSE,
-#endif /* LDAP_CONTROL_SORTRESPONSE */
-
-#ifdef LDAP_CONTROL_VLVREQUEST
-       LDAP_CONTROL_VLVREQUEST,
-#endif /* LDAP_CONTROL_VLVREQUEST */
-
-#ifdef LDAP_CONTROL_VLVRESPONSE
-       LDAP_CONTROL_VLVRESPONSE,
-#endif /* LDAP_CONTROL_VLVRESPONSE */
-
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
-       LDAP_CONTROL_VALUESRETURNFILTER,
-#endif /* LDAP_CONTROL_VALUESRETURNFILTER */
-
-       NULL
-};
-
 int
 slap_init( int mode, const char *name )
 {
index 6c74b449b752847282fc28326fbb7adb53bd8265..7fae9b282fb226c3883a7b5e5c93394535f7fc30 100644 (file)
@@ -1,6 +1,6 @@
 /* limits.c - routines to handle regex-based size and time limits */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -563,7 +563,6 @@ parse_limit(
                                        }
                                }
 
-#ifdef LDAP_CONTROL_PAGEDRESULTS
                        } else if ( strncasecmp( arg, "pr", sizeof( "pr" ) - 1 ) == 0 ) {
                                arg += sizeof( "pr" ) - 1;
                                if ( arg[0] != '=' ) {
@@ -581,7 +580,6 @@ parse_limit(
                                                return( 1 );
                                        }
                                }
-#endif /* LDAP_CONTROL_PAGEDRESULTS */
                                
                        } else {
                                return( 1 );
index 1dc199c838d8910bc5d9cdb46ff1c6899725bd8d..70d4b95e03caab56028f1076b3005920115caf67 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #include "portable.h"
@@ -17,6 +17,9 @@
 #include "ldap_pvt.h"
 
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 #include "lutil.h"
 #include "ldif.h"
 
@@ -81,7 +84,7 @@ static STRDISP        syslog_types[] = {
        { "LOCAL5", sizeof("LOCAL5"), LOG_LOCAL5 },
        { "LOCAL6", sizeof("LOCAL6"), LOG_LOCAL6 },
        { "LOCAL7", sizeof("LOCAL7"), LOG_LOCAL7 },
-       { NULL }
+       { NULL, 0, 0 }
 };
 
 static int   cnvt_str2int( char *, STRDISP_P, int );
@@ -157,7 +160,6 @@ int main( int argc, char **argv )
        }
 #endif
 
-
 #ifdef HAVE_NT_SERVICE_MANAGER
        {
                int *i;
@@ -325,7 +327,6 @@ int main( int argc, char **argv )
        Debug( LDAP_DEBUG_TRACE, "%s", Versionstr, 0, 0 );
 #endif
 
-
        if( serverName == NULL ) {
                if ( (serverName = strrchr( argv[0], *LDAP_DIRSEP )) == NULL ) {
                        serverName = argv[0];
@@ -405,6 +406,20 @@ int main( int argc, char **argv )
        (void) ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &rc );
 #endif
 
+#ifdef LDAP_SLAPI
+       if ( slapi_init() != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, CRIT, "main: slapi initialization error\n", 0, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ANY,
+                   "slapi initialization error\n",
+                   0, 0, 0 );
+#endif
+
+               goto destroy;
+       }
+#endif /* LDAP_SLAPI */
+
        if ( read_config( configfile, 0 ) != 0 ) {
                rc = 1;
                SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
index 0d3986ae2b4f8da8397134954c7318c0aa11a067..ca028564fe024deddafb05bd5b8316ed83c03d3e 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /* 
- * Copyright 1999-2002 The OpenLDAP Foundation.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -70,7 +70,7 @@ filter_matched_values(
        char            ***e_flags
 )
 {
-       ValuesReturnFilter *f;
+       ValuesReturnFilter *vrf;
        int             rc = LDAP_SUCCESS;
 
 #ifdef NEW_LOGGING
@@ -79,22 +79,22 @@ filter_matched_values(
        Debug( LDAP_DEBUG_FILTER, "=> filter_matched_values\n", 0, 0, 0 );
 #endif
 
-       for ( f = op->vrFilter; f != NULL; f = f->f_next ) {
-               switch ( f->f_choice ) {
+       for ( vrf = op->vrFilter; vrf != NULL; vrf = vrf->vrf_next ) {
+               switch ( vrf->vrf_choice ) {
                case SLAPD_FILTER_COMPUTED:
 #ifdef NEW_LOGGING
                        LDAP_LOG( FILTER, DETAIL1, 
                                "test_vrFilter: COMPUTED %s (%d)\n",
-                               f->f_result == LDAP_COMPARE_FALSE ? "false" :
-                               f->f_result == LDAP_COMPARE_TRUE         ? "true"  :
-                               f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
-                               "error", f->f_result, 0 );
+                               vrf->vrf_result == LDAP_COMPARE_FALSE ? "false" :
+                               vrf->vrf_result == LDAP_COMPARE_TRUE     ? "true"  :
+                               vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
+                               "error", vrf->vrf_result, 0 );
 #else
                        Debug( LDAP_DEBUG_FILTER, "     COMPUTED %s (%d)\n",
-                               f->f_result == LDAP_COMPARE_FALSE ? "false" :
-                               f->f_result == LDAP_COMPARE_TRUE ? "true" :
-                               f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" : "error",
-                               f->f_result, 0 );
+                               vrf->vrf_result == LDAP_COMPARE_FALSE ? "false" :
+                               vrf->vrf_result == LDAP_COMPARE_TRUE ? "true" :
+                               vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined" : "error",
+                               vrf->vrf_result, 0 );
 #endif
                        /*This type of filter does not affect the result */
                        rc = LDAP_SUCCESS;
@@ -106,7 +106,7 @@ filter_matched_values(
 #else
                        Debug( LDAP_DEBUG_FILTER, "     EQUALITY\n", 0, 0, 0 );
 #endif
-                       rc = test_ava_vrFilter( be, conn, op, a, f->f_ava,
+                       rc = test_ava_vrFilter( be, conn, op, a, vrf->vrf_ava,
                                LDAP_FILTER_EQUALITY, e_flags );
                        if( rc == -1 ) {
                                return rc;
@@ -121,7 +121,7 @@ filter_matched_values(
 #endif
 
                        rc = test_substrings_vrFilter( be, conn, op, a,
-                               f, e_flags );
+                               vrf, e_flags );
                        if( rc == -1 ) {
                                return rc;
                        }
@@ -134,14 +134,14 @@ filter_matched_values(
                        Debug( LDAP_DEBUG_FILTER, "     PRESENT\n", 0, 0, 0 );
 #endif
                        rc = test_presence_vrFilter( be, conn, op, a,
-                               f->f_desc, e_flags );
+                               vrf->vrf_desc, e_flags );
                        if( rc == -1 ) {
                                return rc;
                        }
                        break;
 
                case LDAP_FILTER_GE:
-                       rc = test_ava_vrFilter( be, conn, op, a, f->f_ava,
+                       rc = test_ava_vrFilter( be, conn, op, a, vrf->vrf_ava,
                                LDAP_FILTER_GE, e_flags );
                        if( rc == -1 ) {
                                return rc;
@@ -149,7 +149,7 @@ filter_matched_values(
                        break;
 
                case LDAP_FILTER_LE:
-                       rc = test_ava_vrFilter( be, conn, op, a, f->f_ava,
+                       rc = test_ava_vrFilter( be, conn, op, a, vrf->vrf_ava,
                                LDAP_FILTER_LE, e_flags );
                        if( rc == -1 ) {
                                return rc;
@@ -163,7 +163,7 @@ filter_matched_values(
                        Debug( LDAP_DEBUG_FILTER, "     EXT\n", 0, 0, 0 );
 #endif
                        rc = test_mra_vrFilter( be, conn, op, a,
-                               f->f_mra, e_flags );
+                               vrf->vrf_mra, e_flags );
                        if( rc == -1 ) {
                                return rc;
                        }
@@ -172,10 +172,10 @@ filter_matched_values(
                default:
 #ifdef NEW_LOGGING
                        LDAP_LOG( FILTER, INFO, 
-                               "test_vrFilter:  unknown filter type %lu\n", f->f_choice, 0, 0 );
+                               "test_vrFilter:  unknown filter type %lu\n", vrf->vrf_choice, 0, 0 );
 #else
                        Debug( LDAP_DEBUG_ANY, "        unknown filter type %lu\n",
-                               f->f_choice, 0, 0 );
+                               vrf->vrf_choice, 0, 0 );
 #endif
                        rc = LDAP_PROTOCOL_ERROR;
                } 
@@ -303,7 +303,7 @@ test_substrings_vrFilter(
        Connection      *conn,
        Operation       *op,
        Attribute       *a,
-       ValuesReturnFilter *f,
+       ValuesReturnFilter *vrf,
        char            ***e_flags
 )
 {
@@ -313,7 +313,7 @@ test_substrings_vrFilter(
                MatchingRule *mr = a->a_desc->ad_type->sat_substr;
                struct berval *bv;
 
-               if ( !is_ad_subtype( a->a_desc, f->f_sub_desc ) ) {
+               if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
                        continue;
                }
 
@@ -328,7 +328,7 @@ test_substrings_vrFilter(
 
                        rc = value_match( &ret, a->a_desc, mr,
                                SLAP_MR_ASSERTION_SYNTAX_MATCH,
-                               bv, f->f_sub, &text );
+                               bv, vrf->vrf_sub, &text );
 
                        if( rc != LDAP_SUCCESS ) {
                                return rc;
index 0f0c716375f167e6de35b1ba47d6d786746912de..051722533ff9f57c2bc510035d9d9952cc3a1beb 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -27,6 +27,9 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 
 int
 do_modify(
@@ -43,6 +46,10 @@ do_modify(
        Modifications   **modtail = &modlist;
 #ifdef LDAP_DEBUG
        Modifications *tmp;
+#endif
+#ifdef LDAP_SLAPI
+       LDAPMod         **modv = NULL;
+       Slapi_PBlock *pb = op->o_pb;
 #endif
        Backend         *be;
        int rc;
@@ -118,7 +125,7 @@ do_modify(
                mod->sml_type = tmp.sml_type;
                mod->sml_bvalues = tmp.sml_bvalues;
                mod->sml_desc = NULL;
-               mod->sml_next =NULL;
+               mod->sml_next = NULL;
                *modtail = mod;
 
                switch( mop ) {
@@ -265,8 +272,32 @@ do_modify(
        }
 #endif
 
-       Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD dn=\"%s\"\n",
-           op->o_connid, op->o_opid, dn.bv_val, 0, 0 );
+       if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
+               char abuf[BUFSIZ/2], *ptr = abuf;
+               int len = 0;
+
+               Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD dn=\"%s\"\n",
+                       op->o_connid, op->o_opid, dn.bv_val, 0, 0 );
+
+               for ( tmp = modlist; tmp != NULL; tmp = tmp->sml_next ) {
+                       if (len + 1 + tmp->sml_type.bv_len > sizeof(abuf)) {
+                               Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD attr=%s\n",
+                                   op->o_connid, op->o_opid, abuf, 0, 0 );
+                               len = 0;
+                               ptr = abuf;
+                       }
+                       if (len) {
+                               *ptr++ = ' ';
+                               len++;
+                       }
+                       ptr = lutil_strcopy(ptr, tmp->sml_type.bv_val);
+                       len += tmp->sml_type.bv_len;
+               }
+               if (len) {
+                       Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD attr=%s\n",
+                               op->o_connid, op->o_opid, abuf, 0, 0 );
+               }
+       }
 
        manageDSAit = get_manageDSAit( op );
 
@@ -303,6 +334,48 @@ do_modify(
        /* deref suffix alias if appropriate */
        suffix_alias( be, &ndn );
 
+#if defined( LDAP_SLAPI )
+       slapi_x_backend_set_pb( pb, be );
+       slapi_x_connection_set_pb( pb, conn );
+       slapi_x_operation_set_pb( pb, op );
+       slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+       modv = slapi_x_modifications2ldapmods( &modlist );
+       slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)modv );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_MODIFY_FN, pb );
+       if ( rc != 0 ) {
+               /*
+                * A preoperation plugin failure will abort the
+                * entire operation.
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_modify: modify preoperation plugin "
+                               "failed\n", 0, 0, 0 );
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_modify: modify preoperation plugin failed.\n",
+                               0, 0, 0);
+#endif
+               if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0) {
+                       rc = LDAP_OTHER;
+               }
+               ldap_mods_free( modv, 1 );
+               modv = NULL;
+               goto cleanup;
+       }
+
+       /*
+        * It's possible that the preoperation plugin changed the
+        * modification array, so we need to convert it back to
+        * a Modification list.
+        *
+        * Calling slapi_x_modifications2ldapmods() destroyed modlist so
+        * we don't need to free it.
+        */
+       slapi_pblock_get( pb, SLAPI_MODIFY_MODS, (void **)&modv );
+       modlist = slapi_x_ldapmods2modifications( modv );
+#endif /* defined( LDAP_SLAPI ) */
+
        /*
         * do the modify if 1 && (2 || 3)
         * 1) there is a modify function implemented in this backend;
@@ -380,11 +453,25 @@ do_modify(
                        NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       if ( doPluginFNs( be, SLAPI_PLUGIN_POST_MODIFY_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_modify: modify postoperation plugins "
+                               "failed\n", 0, 0, 0 );
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_modify: modify postoperation plugins "
+                               "failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        free( pdn.bv_val );
        free( ndn.bv_val );
-       if ( modlist != NULL )
-               slap_mods_free( modlist );
+       if ( modlist != NULL ) slap_mods_free( modlist );
+#if defined( LDAP_SLAPI )
+       if ( modv != NULL ) slapi_x_free_ldapmods( modv );
+#endif
        return rc;
 }
 
@@ -437,10 +524,10 @@ int slap_mods_check(
                        return LDAP_UNDEFINED_TYPE;
                }
 
-               if( slap_ad_is_lang_range( ad )) {
+               if( slap_ad_is_tag_range( ad )) {
                        /* attribute requires binary transfer */
                        snprintf( textbuf, textlen,
-                               "%s: inappropriate use of language range option",
+                               "%s: inappropriate use of tag range option",
                                ml->sml_type.bv_val );
                        *text = textbuf;
                        return LDAP_UNDEFINED_TYPE;
@@ -679,3 +766,4 @@ int slap_mods_opattrs(
        *modtail = NULL;
        return LDAP_SUCCESS;
 }
+
index 372f0a33e8a15b19a581a1486cd52731edbd1ba4..3c88a024737db311a71c9db9a01c91609027bba8 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -37,6 +37,9 @@
 
 #include "ldap_pvt.h"
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 
 int
 do_modrdn(
@@ -64,6 +67,10 @@ do_modrdn(
        const char *text;
        int manageDSAit;
 
+#ifdef LDAP_SLAPI
+       Slapi_PBlock *pb = op->o_pb;
+#endif
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_modrdn: begin\n", 0, 0, 0 );
 #else
@@ -324,6 +331,36 @@ do_modrdn(
        /* deref suffix alias if appropriate */
        suffix_alias( be, &ndn );
 
+#if defined( LDAP_SLAPI )
+       slapi_x_backend_set_pb( pb, be );
+       slapi_x_connection_set_pb( pb, conn );
+       slapi_x_operation_set_pb( pb, op );
+       slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)dn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn.bv_val );
+       slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR,
+                       (void *)newSuperior.bv_val );
+       slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)deloldrdn );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_MODRDN_FN, pb );
+       if ( rc != 0 ) {
+               /*
+                * A preoperation plugin failure will abort the
+                * entire operation.
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn preoperation plugin "
+                               "failed\n", 0, 0, 0 );
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_modrdn: modrdn preoperation plugin "
+                               "failed.\n", 0, 0, 0);
+#endif
+               if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0)
+                       rc = LDAP_OTHER;
+               goto cleanup;
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
        /*
         * do the add if 1 && (2 || 3)
         * 1) there is an add function implemented in this backend;
@@ -370,6 +407,18 @@ do_modrdn(
                        NULL, NULL );
        }
 
+#if defined( LDAP_SLAPI )
+       if ( doPluginFNs( be, SLAPI_PLUGIN_POST_MODRDN_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn postoperation plugins "
+                               "failed\n", 0, 0, 0 );
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_modrdn: modrdn postoperation plugins "
+                               "failed.\n", 0, 0, 0);
+#endif
+       }
+#endif /* defined( LDAP_SLAPI ) */
+
 cleanup:
        free( pdn.bv_val );
        free( ndn.bv_val );
index 4b1166d2847bf394c2485d4caea6e90056ea93dc..81b6930cbe6d3dba03a5bbe98ba57484511c61fa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -24,11 +24,12 @@ modify_check_duplicates(
        MatchingRule            *mr,
        BerVarray               vals,
        BerVarray               mods,
+       int                     permissive,
        const char      **text,
        char *textbuf, size_t textlen )
 {
        int             i, j, numvals = 0, nummods,
-                       rc = LDAP_SUCCESS;
+                       rc = LDAP_SUCCESS, matched;
        BerVarray       nvals = NULL, nmods = NULL;
 
        /*
@@ -130,7 +131,7 @@ modify_check_duplicates(
                }
 
                if ( numvals > 0 && numvals < nummods ) {
-                       for ( j = 0; nvals[ j ].bv_val; j++ ) {
+                       for ( matched = 0, j = 0; nvals[ j ].bv_val; j++ ) {
                                int match;
 
                                rc = (*mr->smr_match)( &match,
@@ -145,8 +146,12 @@ modify_check_duplicates(
                                                ad->ad_cname.bv_val );
                                        goto return_results;
                                }
-       
+
                                if ( match == 0 ) {
+                                       if ( permissive ) {
+                                               matched++;
+                                               continue;
+                                       }
                                        *text = textbuf;
                                        snprintf( textbuf, textlen,
                                                "%s: value #%d provided more than once",
@@ -156,9 +161,15 @@ modify_check_duplicates(
                                        goto return_results;
                                }
                        }
+
+                       if ( permissive && matched == j ) {
+                               nmods[ i + 1 ].bv_val = NULL;
+                               rc = LDAP_TYPE_OR_VALUE_EXISTS;
+                               goto return_results;
+                       }
                }
        
-               for ( j = 0; j < i; j++ ) {
+               for ( matched = 0, j = 0; j < i; j++ ) {
                        int match;
 
                        rc = (*mr->smr_match)( &match,
@@ -175,6 +186,10 @@ modify_check_duplicates(
                        }
 
                        if ( match == 0 ) {
+                               if ( permissive ) {
+                                       matched++;
+                                       continue;
+                               }
                                *text = textbuf;
                                snprintf( textbuf, textlen,
                                        "%s: value #%d provided more than once",
@@ -184,6 +199,12 @@ modify_check_duplicates(
                                goto return_results;
                        }
                }
+
+               if ( permissive && matched == j ) {
+                       nmods[ i + 1 ].bv_val = NULL;
+                       rc = LDAP_TYPE_OR_VALUE_EXISTS;
+                       goto return_results;
+               }
        }
        nmods[ i ].bv_val = NULL;
 
@@ -205,7 +226,7 @@ modify_check_duplicates(
                                goto return_results;
                        }
 
-                       for ( i = 0; nmods[ i ].bv_val; i++ ) {
+                       for ( matched = 0, i = 0; nmods[ i ].bv_val; i++ ) {
                                int match;
 
                                rc = (*mr->smr_match)( &match,
@@ -221,6 +242,10 @@ modify_check_duplicates(
                                }
 
                                if ( match == 0 ) {
+                                       if ( permissive ) {
+                                               matched++;
+                                               continue;
+                                       }
                                        *text = textbuf;
                                        snprintf( textbuf, textlen,
                                                "%s: value #%d provided more than once",
@@ -230,6 +255,10 @@ modify_check_duplicates(
                                }
                        }
 
+                       if ( permissive && matched == i ) {
+                               rc = LDAP_TYPE_OR_VALUE_EXISTS;
+                               goto return_results;
+                       }
                }
        }
 
@@ -248,11 +277,13 @@ int
 modify_add_values(
        Entry   *e,
        Modification    *mod,
+       int     permissive,
        const char      **text,
        char *textbuf, size_t textlen
 )
 {
        int             i, j;
+       int             matched;
        Attribute       *a;
        MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
        const char *op;
@@ -271,6 +302,12 @@ modify_add_values(
 
        a = attr_find( e->e_attrs, mod->sm_desc );
 
+       /*
+        * With permissive set, as long as the attribute being added
+        * has the same value(s?) as the existing attribute, then the
+        * modify will succeed.
+        */
+
        /* check if the values we're adding already exist */
        if( mr == NULL || !mr->smr_match ) {
                if ( a != NULL ) {
@@ -286,10 +323,13 @@ modify_add_values(
                for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
                        /* test asserted values against existing values */
                        if( a ) {
-                               for( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
+                               for( matched = 0, j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
                                        if ( bvmatch( &mod->sm_bvalues[i],
                                                &a->a_vals[j] ) ) {
-
+                                               if ( permissive ) {
+                                                       matched++;
+                                                       continue;
+                                               }
                                                /* value exists already */
                                                *text = textbuf;
                                                snprintf( textbuf, textlen,
@@ -298,6 +338,10 @@ modify_add_values(
                                                return LDAP_TYPE_OR_VALUE_EXISTS;
                                        }
                                }
+                               if ( permissive && matched == j ) {
+                                       /* values already exist; do nothing */
+                                       return LDAP_SUCCESS;
+                               }
                        }
 
                        /* test asserted values against themselves */
@@ -357,7 +401,7 @@ modify_add_values(
                                        return rc;
                                }
 
-                               for ( i = 0; a->a_vals[ i ].bv_val; i++ ) {
+                               for ( matched = 0, i = 0; a->a_vals[ i ].bv_val; i++ ) {
                                        int     match;
 
                                        rc = value_match( &match, mod->sm_desc, mr,
@@ -365,6 +409,10 @@ modify_add_values(
                                                &a->a_vals[ i ], &asserted, text );
 
                                        if( rc == LDAP_SUCCESS && match == 0 ) {
+                                               if ( permissive ) {
+                                                       matched++;
+                                                       continue;
+                                               }
                                                free( asserted.bv_val );
                                                *text = textbuf;
                                                snprintf( textbuf, textlen,
@@ -373,13 +421,22 @@ modify_add_values(
                                                return LDAP_TYPE_OR_VALUE_EXISTS;
                                        }
                                }
+                               if ( permissive && matched == i ) {
+                                       /* values already exist; do nothing */
+                                       return LDAP_SUCCESS;
+                               }
                        }
 
                } else {
                        rc = modify_check_duplicates( mod->sm_desc, mr,
                                        a ? a->a_vals : NULL, mod->sm_bvalues,
+                                       permissive,
                                        text, textbuf, textlen );
-       
+
+                       if ( permissive && rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
+                               return LDAP_SUCCESS;
+                       }
+
                        if ( rc != LDAP_SUCCESS ) {
                                return rc;
                        }
@@ -403,6 +460,7 @@ int
 modify_delete_values(
        Entry   *e,
        Modification    *mod,
+       int     permissive,
        const char      **text,
        char *textbuf, size_t textlen
 )
@@ -413,11 +471,18 @@ modify_delete_values(
        BerVarray       nvals = NULL;
        char            dummy = '\0';
 
+       /*
+        * If permissive is set, then the non-existence of an 
+        * attribute is not treated as an error.
+        */
+
        /* delete the entire attribute */
        if ( mod->sm_bvalues == NULL ) {
                rc = attr_delete( &e->e_attrs, mod->sm_desc );
 
-               if( rc != LDAP_SUCCESS ) {
+               if( permissive ) {
+                       rc = LDAP_SUCCESS;
+               } else if( rc != LDAP_SUCCESS ) {
                        *text = textbuf;
                        snprintf( textbuf, textlen,
                                "modify/delete: %s: no such attribute",
@@ -439,6 +504,9 @@ modify_delete_values(
 
        /* delete specific values - find the attribute first */
        if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) {
+               if( permissive ) {
+                       return LDAP_SUCCESS;
+               }
                *text = textbuf;
                snprintf( textbuf, textlen,
                        "modify/delete: %s: no such attribute",
@@ -581,6 +649,7 @@ int
 modify_replace_values(
        Entry   *e,
        Modification    *mod,
+       int             permissive,
        const char      **text,
        char *textbuf, size_t textlen
 )
@@ -588,7 +657,7 @@ modify_replace_values(
        (void) attr_delete( &e->e_attrs, mod->sm_desc );
 
        if ( mod->sm_bvalues ) {
-               return modify_add_values( e, mod, text, textbuf, textlen );
+               return modify_add_values( e, mod, permissive, text, textbuf, textlen );
        }
 
        return LDAP_SUCCESS;
index 2dd747458d605f25b2539437d82df571e20083da..498622cdd15b5de61d1b72c30a53ca6c99422a87 100644 (file)
@@ -242,7 +242,7 @@ static int module_unload (module_loaded_t *module)
                }
 
                /* call module's terminate routine, if present */
-               if (terminate = lt_dlsym(module->lib, "term_module")) {
+               if ((terminate = lt_dlsym(module->lib, "term_module"))) {
                        terminate();
                }
 
index 58e5c960a43532460c674c20db74a8175cbd7f71..ad00a1ece3497a41ae2ba1b21c6a1d5baf0aa24b 100644 (file)
@@ -1,7 +1,7 @@
 /* mr.c - routines to manage matching rule definitions */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -22,15 +22,19 @@ struct mindexrec {
 };
 
 static Avlnode *mr_index = NULL;
-static MatchingRule *mr_list = NULL;
-static MatchingRuleUse *mru_list = NULL;
+static LDAP_SLIST_HEAD(MRList, slap_matching_rule) mr_list
+       = LDAP_SLIST_HEAD_INITIALIZER(&mr_list);
+static LDAP_SLIST_HEAD(MRUList, slap_matching_rule_use) mru_list
+       = LDAP_SLIST_HEAD_INITIALIZER(&mru_list);
 
 static int
 mr_index_cmp(
-    struct mindexrec   *mir1,
-    struct mindexrec   *mir2
+    const void *v_mir1,
+    const void *v_mir2
 )
 {
+       const struct mindexrec  *mir1 = v_mir1;
+       const struct mindexrec  *mir2 = v_mir2;
        int i = mir1->mir_name.bv_len - mir2->mir_name.bv_len;
        if (i) return i;
        return (strcmp( mir1->mir_name.bv_val, mir2->mir_name.bv_val ));
@@ -38,10 +42,12 @@ mr_index_cmp(
 
 static int
 mr_index_name_cmp(
-    struct berval      *name,
-    struct mindexrec   *mir
+    const void *v_name,
+    const void *v_mir
 )
 {
+       const struct berval    *name = v_name;
+       const struct mindexrec *mir  = v_mir;
        int i = name->bv_len - mir->mir_name.bv_len;
        if (i) return i;
        return (strncmp( name->bv_val, mir->mir_name.bv_val, name->bv_len ));
@@ -62,8 +68,7 @@ mr_bvfind( struct berval *mrname )
 {
        struct mindexrec        *mir = NULL;
 
-       if ( (mir = (struct mindexrec *) avl_find( mr_index, mrname,
-           (AVL_CMP) mr_index_name_cmp )) != NULL ) {
+       if ( (mir = avl_find( mr_index, mrname, mr_index_name_cmp )) != NULL ) {
                return( mir->mir_mr );
        }
        return( NULL );
@@ -72,11 +77,12 @@ mr_bvfind( struct berval *mrname )
 void
 mr_destroy( void )
 {
-       MatchingRule *m, *n;
+       MatchingRule *m;
 
        avl_free(mr_index, ldap_memfree);
-       for (m=mr_list; m; m=n) {
-               n = m->smr_next;
+       while( !LDAP_SLIST_EMPTY(&mr_list) ) {
+               m = LDAP_SLIST_FIRST(&mr_list);
+               LDAP_SLIST_REMOVE_HEAD(&mr_list, smr_next);
                ch_free( m->smr_str.bv_val );
                ldap_matchingrule_free((LDAPMatchingRule *)m);
        }
@@ -88,15 +94,10 @@ mr_insert(
     const char         **err
 )
 {
-       MatchingRule            **mrp;
        struct mindexrec        *mir;
        char                    **names;
 
-       mrp = &mr_list;
-       while ( *mrp != NULL ) {
-               mrp = &(*mrp)->smr_next;
-       }
-       *mrp = smr;
+       LDAP_SLIST_INSERT_HEAD(&mr_list, smr, smr_next);
 
        if ( smr->smr_oid ) {
                mir = (struct mindexrec *)
@@ -105,8 +106,7 @@ mr_insert(
                mir->mir_name.bv_len = strlen( smr->smr_oid );
                mir->mir_mr = smr;
                if ( avl_insert( &mr_index, (caddr_t) mir,
-                                (AVL_CMP) mr_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
+                                mr_index_cmp, avl_dup_error ) ) {
                        *err = smr->smr_oid;
                        ldap_memfree(mir);
                        return SLAP_SCHERR_MR_DUP;
@@ -122,8 +122,7 @@ mr_insert(
                        mir->mir_name.bv_len = strlen( *names );
                        mir->mir_mr = smr;
                        if ( avl_insert( &mr_index, (caddr_t) mir,
-                                        (AVL_CMP) mr_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) ) {
+                                        mr_index_cmp, avl_dup_error ) ) {
                                *err = *names;
                                ldap_memfree(mir);
                                return SLAP_SCHERR_MR_DUP;
@@ -286,10 +285,12 @@ register_matching_rule(
 void
 mru_destroy( void )
 {
-       MatchingRuleUse *m, *n;
+       MatchingRuleUse *m;
+
+       while( !LDAP_SLIST_EMPTY(&mru_list) ) {
+               m = LDAP_SLIST_FIRST(&mru_list);
+               LDAP_SLIST_REMOVE_HEAD(&mru_list, smru_next);
 
-       for (m=mru_list; m; m=n) {
-               n = m->smru_next;
                if ( m->smru_str.bv_val ) {
                        ch_free( m->smru_str.bv_val );
                }
@@ -308,7 +309,7 @@ int
 matching_rule_use_init( void )
 {
        MatchingRule    *mr;
-       MatchingRuleUse **mru_ptr = &mru_list;
+       MatchingRuleUse **mru_ptr = &LDAP_SLIST_FIRST(&mru_list);
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, INFO, "matching_rule_use_init\n", 0, 0, 0 );
@@ -316,9 +317,9 @@ matching_rule_use_init( void )
        Debug( LDAP_DEBUG_TRACE, "matching_rule_use_init\n", 0, 0, 0 );
 #endif
 
-       for ( mr = mr_list; mr; mr = mr->smr_next ) {
+       LDAP_SLIST_FOREACH( mr, &mr_list, smr_next ) {
                AttributeType   *at;
-               MatchingRuleUse _mru, *mru = &_mru;
+               MatchingRuleUse mru_storage, *mru = &mru_storage;
 
                char            **applies_oids = NULL;
 
@@ -352,7 +353,7 @@ matching_rule_use_init( void )
                mru->smru_mr = mr;
                mru->smru_obsolete = mr->smr_obsolete;
                mru->smru_applies_oids = NULL;
-               mru->smru_next = NULL;
+               LDAP_SLIST_NEXT(mru, smru_next) = NULL;
                mru->smru_oid = mr->smr_oid;
                mru->smru_names = mr->smr_names;
                mru->smru_desc = mr->smr_desc;
@@ -401,11 +402,11 @@ matching_rule_use_init( void )
                        /* call-forward from MatchingRule to MatchingRuleUse */
                        mr->smr_mru = mru;
                        /* copy static data to newly allocated struct */
-                       *mru = _mru;
+                       *mru = mru_storage;
                        /* append the struct pointer to the end of the list */
                        *mru_ptr = mru;
                        /* update the list head pointer */
-                       mru_ptr = &mru->smru_next;
+                       mru_ptr = &LDAP_SLIST_NEXT(mru,smru_next);
                }
        }
 
@@ -436,11 +437,11 @@ int mr_usable_with_at(
 
 int mr_schema_info( Entry *e )
 {
-       MatchingRule    *mr;
+       MatchingRule *mr;
 
        AttributeDescription *ad_matchingRules = slap_schema.si_ad_matchingRules;
 
-       for ( mr = mr_list; mr; mr = mr->smr_next ) {
+       LDAP_SLIST_FOREACH(mr, &mr_list, smr_next ) {
                if ( mr->smr_usage & SLAP_MR_HIDE ) {
                        /* skip hidden rules */
                        continue;
@@ -473,7 +474,7 @@ int mru_schema_info( Entry *e )
        AttributeDescription *ad_matchingRuleUse 
                = slap_schema.si_ad_matchingRuleUse;
 
-       for ( mru = mru_list; mru; mru = mru->smru_next ) {
+       LDAP_SLIST_FOREACH( mru, &mru_list, smru_next ) {
 
                assert( !( mru->smru_usage & SLAP_MR_HIDE ) );
 
index 14c0ac2e345bb89b2b2d7bd186ac78fef807b4fe..e1564ab7fb1b24a755a363a80a66cc63ec0d6338 100644 (file)
@@ -1,7 +1,7 @@
 /* oc.c - object class routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -75,7 +75,7 @@ int is_entry_objectclass(
 
        if( set_flags && ( e->e_ocflags & SLAP_OC__END )) {
                /* flags are set, use them */
-               return e->e_ocflags & oc->soc_flags & SLAP_OC__MASK;
+               return (e->e_ocflags & oc->soc_flags & SLAP_OC__MASK) != 0;
        }
 
        /*
@@ -114,7 +114,7 @@ int is_entry_objectclass(
        /* mark flags as set */
        e->e_ocflags |= SLAP_OC__END;
 
-       return e->e_ocflags & oc->soc_flags & SLAP_OC__MASK;
+       return (e->e_ocflags & oc->soc_flags & SLAP_OC__MASK) != 0;
 }
 
 
@@ -124,13 +124,15 @@ struct oindexrec {
 };
 
 static Avlnode *oc_index = NULL;
-static ObjectClass *oc_list = NULL;
+static LDAP_SLIST_HEAD(OCList, slap_object_class) oc_list
+       = LDAP_SLIST_HEAD_INITIALIZER(&oc_list);
 
 static int
 oc_index_cmp(
-    struct oindexrec   *oir1,
-    struct oindexrec   *oir2 )
+       const void *v_oir1,
+       const void *v_oir2 )
 {
+       const struct oindexrec *oir1 = v_oir1, *oir2 = v_oir2;
        int i = oir1->oir_name.bv_len - oir2->oir_name.bv_len;
        if (i)
                return i;
@@ -139,9 +141,11 @@ oc_index_cmp(
 
 static int
 oc_index_name_cmp(
-    struct berval      *name,
-    struct oindexrec   *oir )
+       const void *v_name,
+       const void *v_oir )
 {
+       const struct berval    *name = v_name;
+       const struct oindexrec *oir  = v_oir;
        int i = name->bv_len - oir->oir_name.bv_len;
        if (i)
                return i;
@@ -164,8 +168,7 @@ oc_bvfind( struct berval *ocname )
 {
        struct oindexrec        *oir;
 
-       oir = (struct oindexrec *) avl_find( oc_index, ocname,
-            (AVL_CMP) oc_index_name_cmp );
+       oir = avl_find( oc_index, ocname, oc_index_name_cmp );
 
        if ( oir != NULL ) {
                return( oir->oir_oc );
@@ -329,12 +332,13 @@ oc_add_sups(
 void
 oc_destroy( void )
 {
-       ObjectClass *o, *n;
+       ObjectClass *o;
 
        avl_free(oc_index, ldap_memfree);
-       for (o=oc_list; o; o=n)
-       {
-               n = o->soc_next;
+       while( !LDAP_SLIST_EMPTY(&oc_list) ) {
+               o = LDAP_SLIST_FIRST(&oc_list);
+               LDAP_SLIST_REMOVE_HEAD(&oc_list, soc_next);
+
                if (o->soc_sups) ldap_memfree(o->soc_sups);
                if (o->soc_required) ldap_memfree(o->soc_required);
                if (o->soc_allowed) ldap_memfree(o->soc_allowed);
@@ -348,15 +352,10 @@ oc_insert(
     const char         **err
 )
 {
-       ObjectClass     **ocp;
        struct oindexrec        *oir;
        char                    **names;
 
-       ocp = &oc_list;
-       while ( *ocp != NULL ) {
-               ocp = &(*ocp)->soc_next;
-       }
-       *ocp = soc;
+       LDAP_SLIST_INSERT_HEAD( &oc_list, soc, soc_next );
 
        if ( soc->soc_oid ) {
                oir = (struct oindexrec *)
@@ -369,8 +368,7 @@ oc_insert(
                assert( oir->oir_oc );
 
                if ( avl_insert( &oc_index, (caddr_t) oir,
-                                (AVL_CMP) oc_index_cmp,
-                                (AVL_DUP) avl_dup_error ) )
+                                oc_index_cmp, avl_dup_error ) )
                {
                        *err = soc->soc_oid;
                        ldap_memfree(oir);
@@ -393,8 +391,7 @@ oc_insert(
                        assert( oir->oir_oc );
 
                        if ( avl_insert( &oc_index, (caddr_t) oir,
-                                        (AVL_CMP) oc_index_cmp,
-                                        (AVL_DUP) avl_dup_error ) )
+                                        oc_index_cmp, avl_dup_error ) )
                        {
                                *err = *names;
                                ldap_memfree(oir);
@@ -489,7 +486,7 @@ oc_schema_info( Entry *e )
 
        vals[1].bv_val = NULL;
 
-       for ( oc = oc_list; oc; oc = oc->soc_next ) {
+       LDAP_SLIST_FOREACH( oc, &oc_list, soc_next ) {
                if( oc->soc_flags & SLAP_OC_HIDE ) continue;
 
                if ( ldap_objectclass2bv( &oc->soc_oclass, vals ) == NULL ) {
index 4075171d13f18169c89b35fe0c5aedb5d483c0e1..89895ad6c3b3e0d1d5c9c3278bdbbab495214617 100644 (file)
@@ -1,7 +1,7 @@
 /* schemaparse.c - routines to parse config file objectclass definitions */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -15,7 +15,8 @@
 
 #include "slap.h"
 
-static OidMacro *om_list = NULL;
+static LDAP_SLIST_HEAD(OidMacroList, slap_oid_macro) om_list
+       = LDAP_SLIST_HEAD_INITIALIZER(om_list);
 
 /* Replace an OID Macro invocation with its full numeric OID.
  * If the macro is used with "macroname:suffix" append ".suffix"
@@ -31,7 +32,7 @@ oidm_find(char *oid)
                return oid;
        }
 
-    for (om = om_list; om; om=om->som_next) {
+       LDAP_SLIST_FOREACH( om, &om_list, som_next ) {
                char **names = om->som_names;
 
                if( names == NULL ) {
@@ -71,13 +72,16 @@ oidm_find(char *oid)
 void
 oidm_destroy()
 {
-       OidMacro *om, *n;
+       OidMacro *om;
+
+       while( !LDAP_SLIST_EMPTY( &om_list )) {
+               om = LDAP_SLIST_FIRST( &om_list );
 
-       for (om = om_list; om; om = n) {
-               n = om->som_next;
                ldap_charray_free(om->som_names);
                free(om->som_oid.bv_val);
                free(om);
+               
+               LDAP_SLIST_REMOVE_HEAD( &om_list, som_next );
        }
 }
 
@@ -133,8 +137,8 @@ usage:      fprintf( stderr, "\tObjectIdentifier <name> <oid>\n");
        }
 
        om->som_oid.bv_len = strlen( om->som_oid.bv_val );
-       om->som_next = om_list;
-       om_list = om;
+
+       LDAP_SLIST_INSERT_HEAD( &om_list, om, som_next );
 
        return 0;
 }
index 59fc1b9cd7e7c494388081a8406c3fc05fc79b9c..ae7594ce86273c02c767e31cd61eba6b232c36a9 100644 (file)
@@ -1,7 +1,7 @@
 /* operation.c - routines to deal with pending ldap operations */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -13,6 +13,9 @@
 #include <ac/socket.h>
 
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 
 
 void
@@ -36,11 +39,27 @@ slap_op_free( Operation *op )
                ldap_controls_free( op->o_ctrls );
        }
 
+#ifdef LDAP_CONNECTIONLESS
+       if ( op->o_res_ber != NULL ) {
+               ber_free( op->o_res_ber, 1 );
+       }
+#endif
 #ifdef LDAP_CLIENT_UPDATE
        if ( op->o_clientupdate_state.bv_val != NULL ) {
                free( op->o_clientupdate_state.bv_val );
        }
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#ifdef LDAP_SYNC
+       if ( op->o_sync_state.bv_val != NULL ) {
+               free( op->o_sync_state.bv_val );
+       }
+#endif
+
+#if defined( LDAP_SLAPI )
+       if ( op->o_pb != NULL ) {
+               slapi_pblock_destroy( (Slapi_PBlock *)op->o_pb );
+       }
+#endif /* defined( LDAP_SLAPI ) */
 
        free( (char *) op );
 }
@@ -63,6 +82,13 @@ slap_op_alloc(
 
        op->o_time = slap_get_time();
        op->o_opid = id;
+#ifdef LDAP_CONNECTIONLESS
+       op->o_res_ber = NULL;
+#endif
+
+#if defined( LDAP_SLAPI )
+       op->o_pb = slapi_pblock_new();
+#endif /* defined( LDAP_SLAPI ) */
 
        return( op );
 }
index 441007c0bb0546f45d8573254a5013a3ccb2491e..4b26475dfc5f3655f659b80c992a35a0c13dee93 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 #ifndef PROTO_SLAP_H
@@ -78,13 +78,21 @@ LDAP_SLAPD_F (int) slap_bv2undef_ad LDAP_P((
        AttributeDescription **ad,
        const char **text ));
 
-LDAP_SLAPD_F (AttributeDescription *) ad_find_lang LDAP_P((
+LDAP_SLAPD_F (AttributeDescription *) ad_find_tags LDAP_P((
        AttributeType *type,
-       struct berval *lang ));
+       struct berval *tags ));
 
 LDAP_SLAPD_F (AttributeName *) str2anlist LDAP_P(( AttributeName *an,
        char *str, const char *brkstr ));
-LDAP_SLAPD_F (int) an_find LDAP_P(( AttributeName *a, struct berval *s ));     
+LDAP_SLAPD_F (int) an_find LDAP_P(( AttributeName *a, struct berval *s ));
+LDAP_SLAPD_F (int) ad_define_option LDAP_P(( const char *name,
+       const char *fname, int lineno ));
+
+/*
+ * add.c
+ */
+LDAP_SLAPD_F (int) slap_mods2entry LDAP_P(( Modifications *mods, Entry **e,
+       int repl_user, const char **text, char *textbuf, size_t textlen ));
 
 /*
  * at.c
@@ -271,6 +279,8 @@ LDAP_SLAPD_F (int) get_ctrls LDAP_P((
 
 LDAP_SLAPD_F (char *) get_supported_ctrl LDAP_P((int index));
 
+LDAP_SLAPD_F (slap_mask_t) get_supported_ctrl_mask LDAP_P((int index));
+
 /*
  * config.c
  */
@@ -435,8 +445,8 @@ LDAP_SLAPD_F (int) entry_encode LDAP_P(( Entry *e, struct berval *bv ));
 
 LDAP_SLAPD_F (void) entry_free LDAP_P(( Entry *e ));
 LDAP_SLAPD_F (int) entry_cmp LDAP_P(( Entry *a, Entry *b ));
-LDAP_SLAPD_F (int) entry_dn_cmp LDAP_P(( Entry *a, Entry *b ));
-LDAP_SLAPD_F (int) entry_id_cmp LDAP_P(( Entry *a, Entry *b ));
+LDAP_SLAPD_F (int) entry_dn_cmp LDAP_P(( const void *v_a, const void *v_b ));
+LDAP_SLAPD_F (int) entry_id_cmp LDAP_P(( const void *v_a, const void *v_b ));
 
 /*
  * extended.c
@@ -464,6 +474,11 @@ LDAP_SLAPD_F (int) extops_kill LDAP_P(( void ));
 
 LDAP_SLAPD_F (struct berval *) get_supported_extop LDAP_P((int index));
 
+/*
+ *  * cancel.c
+ *   */
+LDAP_SLAPD_F ( SLAP_EXTOP_MAIN_FN ) cancel_extop;
+
 /*
  * filter.c
  */
@@ -483,9 +498,7 @@ LDAP_SLAPD_F (int) get_vrFilter LDAP_P(( Connection *conn, BerElement *ber,
 LDAP_SLAPD_F (void) vrFilter_free LDAP_P(( ValuesReturnFilter *f ));
 LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( ValuesReturnFilter *f, struct berval *fstr ));
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
 LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter ));
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
 /*
  * filterentry.c
@@ -582,16 +595,19 @@ LDAP_SLAPD_F( int ) slap_mods_opattrs(
  */
 LDAP_SLAPD_F( int ) modify_check_duplicates(
        AttributeDescription *ad, MatchingRule *mr, 
-       BerVarray vals, BerVarray mods,
+       BerVarray vals, BerVarray mods, int permissive, 
        const char **text, char *textbuf, size_t textlen );
 LDAP_SLAPD_F( int ) modify_add_values( Entry *e,
        Modification *mod,
+       int permissive,
        const char **text, char *textbuf, size_t textlen );
 LDAP_SLAPD_F( int ) modify_delete_values( Entry *e,
        Modification *mod,
+       int permissive,
        const char **text, char *textbuf, size_t textlen );
 LDAP_SLAPD_F( int ) modify_replace_values( Entry *e,
        Modification *mod,
+       int permissive,
        const char **text, char *textbuf, size_t textlen );
 
 LDAP_SLAPD_F( void ) slap_mod_free( Modification *mod, int freeit );
@@ -671,20 +687,25 @@ LDAP_SLAPD_F (int) is_object_subclass LDAP_P((
 LDAP_SLAPD_F (int) is_entry_objectclass LDAP_P((
        Entry *, ObjectClass *oc, int set_flags ));
 #define is_entry_alias(e)              \
-       (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_ALIAS) : \
-       is_entry_objectclass((e), slap_schema.si_oc_alias, 1))
+       (((e)->e_ocflags & SLAP_OC__END) \
+        ? (((e)->e_ocflags & SLAP_OC_ALIAS) != 0) \
+        : is_entry_objectclass((e), slap_schema.si_oc_alias, 1))
 #define is_entry_referral(e)   \
-       (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_REFERRAL) : \
-       is_entry_objectclass((e), slap_schema.si_oc_referral, 1))
+       (((e)->e_ocflags & SLAP_OC__END) \
+        ? (((e)->e_ocflags & SLAP_OC_REFERRAL) != 0) \
+        : is_entry_objectclass((e), slap_schema.si_oc_referral, 1))
 #define is_entry_subentry(e)   \
-       (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_SUBENTRY) : \
-       is_entry_objectclass((e), slap_schema.si_oc_subentry, 1))
+       (((e)->e_ocflags & SLAP_OC__END) \
+        ? (((e)->e_ocflags & SLAP_OC_SUBENTRY) != 0) \
+        : is_entry_objectclass((e), slap_schema.si_oc_subentry, 1))
 #define is_entry_collectiveAttributeSubentry(e)        \
-       (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY) : \
-       is_entry_objectclass((e), slap_schema.si_oc_collectiveAttributeSubentry, 1))
+       (((e)->e_ocflags & SLAP_OC__END) \
+        ? (((e)->e_ocflags & SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY) != 0) \
+        : is_entry_objectclass((e), slap_schema.si_oc_collectiveAttributeSubentry, 1))
 #define is_entry_dynamicObject(e)      \
-       (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_DYNAMICOBJECT) : \
-       is_entry_objectclass((e), slap_schema.si_oc_dynamicObject, 1))
+       (((e)->e_ocflags & SLAP_OC__END) \
+        ? (((e)->e_ocflags & SLAP_OC_DYNAMICOBJECT) != 0) \
+        : is_entry_objectclass((e), slap_schema.si_oc_dynamicObject, 1))
 
 LDAP_SLAPD_F (int) oc_schema_info( Entry *e );
 
@@ -775,7 +796,7 @@ LDAP_SLAPD_F (void) replog LDAP_P(( Backend *be, Operation *op,
 /*
  * result.c
  */
-LDAP_SLAPD_F (void) send_ldap_result LDAP_P((
+LDAP_SLAPD_F (void) slap_send_ldap_result LDAP_P((
        Connection *conn, Operation *op,
        ber_int_t err, const char *matched, const char *text,
        BerVarray refs,
@@ -793,7 +814,14 @@ LDAP_SLAPD_F (void) send_ldap_disconnect LDAP_P((
        Connection *conn, Operation *op,
        ber_int_t err, const char *text ));
 
-LDAP_SLAPD_F (void) send_ldap_extended LDAP_P((
+LDAP_SLAPD_F (void) slap_send_ldap_extended LDAP_P((
+       Connection *conn, Operation *op,
+       ber_int_t err, const char *matched,
+       const char *text, BerVarray refs,
+       const char *rspoid, struct berval *rspdata,
+       LDAPControl **ctrls ));
+
+LDAP_SLAPD_F (void) slap_send_ldap_intermediate_resp LDAP_P((
        Connection *conn, Operation *op,
        ber_int_t err, const char *matched,
        const char *text, BerVarray refs,
@@ -805,20 +833,20 @@ LDAP_SLAPD_F (void) send_ldap_partial LDAP_P((
        const char *rspoid, struct berval *rspdata,
        LDAPControl **ctrls ));
 
-LDAP_SLAPD_F (void) send_search_result LDAP_P((
+LDAP_SLAPD_F (void) slap_send_search_result LDAP_P((
        Connection *conn, Operation *op,
        ber_int_t err, const char *matched, const char *text,
        BerVarray refs,
        LDAPControl **ctrls,
        int nentries ));
 
-LDAP_SLAPD_F (int) send_search_reference LDAP_P((
+LDAP_SLAPD_F (int) slap_send_search_reference LDAP_P((
        Backend *be, Connection *conn, Operation *op,
        Entry *e, BerVarray refs,
        LDAPControl **ctrls,
        BerVarray *v2refs ));
 
-LDAP_SLAPD_F (int) send_search_entry LDAP_P((
+LDAP_SLAPD_F (int) slap_send_search_entry LDAP_P((
        Backend *be, Connection *conn, Operation *op,
        Entry *e, AttributeName *attrs, int attrsonly,
        LDAPControl **ctrls ));
@@ -877,6 +905,9 @@ LDAP_SLAPD_F (int) slap_sasl_config(
        const char *fname,
        int lineno );
 
+LDAP_SLAPD_F (int) slap_sasl_getdn( Connection *conn,
+       char *id, int len,
+       char *user_realm, struct berval *dn, int flags );
 
 /*
  * saslauthz.c
@@ -894,6 +925,7 @@ LDAP_SLAPD_F (int) slap_sasl_regexp_config LDAP_P((
 LDAP_SLAPD_F (int) slap_sasl_setpolicy LDAP_P(( const char * ));
 LDAP_SLAPD_F (slap_response) slap_cb_null_response;
 LDAP_SLAPD_F (slap_sresult) slap_cb_null_sresult;
+LDAP_SLAPD_F (slap_sendreference) slap_cb_null_sreference;
 
 
 /*
index 4cfd8f1e2b7faffb8ff12a81f8666c2779030699..2e7534f418398ebb380287192fabc8f43c87528d 100644 (file)
@@ -1,7 +1,7 @@
 /* result.c - routines to send ldap results, errors, and referrals */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -17,6 +17,9 @@
 #include <ac/unistd.h>
 
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 
 static char *v2ref( BerVarray ref, const char *text )
 {
@@ -241,6 +244,12 @@ send_ldap_response(
                return;
        }
                
+#ifdef LDAP_CONNECTIONLESS
+       if (conn->c_is_udp)
+               ber = op->o_res_ber;
+       else
+#endif
+
        ber_init_w_nullc( ber, LBER_USE_DER );
 
 #ifdef NEW_LOGGING
@@ -267,27 +276,12 @@ send_ldap_response(
        }
 
 #ifdef LDAP_CONNECTIONLESS
-       if( conn->c_is_udp ) {
-           rc = ber_write(ber,
-                       (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
-           if (rc != sizeof(struct sockaddr)) {
-#ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, ERR, 
-                       "send_ldap_response: conn %lu  ber_write failed\n",
-                       conn ? conn->c_connid : 0 , 0, 0);
-#else
-               Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
-#endif
-               ber_free_buf( ber );
-               return;
-           }
-       }
-       if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
-           rc = ber_printf( ber, "{is{t{ess" /*"}}}"*/,
-               msgid, "", tag, err,
+       if (conn->c_is_udp && conn->c_protocol == LDAP_VERSION2) {
+               rc = ber_printf( ber, "t{ess" /*"}}"*/,
+                       tag, err,
                matched == NULL ? "" : matched,
                text == NULL ? "" : text );
-       } else
+       } else 
 #endif
        {
            rc = ber_printf( ber, "{it{ess" /*"}}"*/,
@@ -333,12 +327,6 @@ send_ldap_response(
                rc = ber_printf( ber, /*"{"*/ "N}" );
        }
 
-#ifdef LDAP_CONNECTIONLESS
-       if( conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1 ) {
-               rc = ber_printf( ber, /*"{"*/ "N}" );
-       }
-#endif
-
        if ( rc == -1 ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( OPERATION, ERR, 
@@ -348,12 +336,18 @@ send_ldap_response(
                Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+               if (conn->c_is_udp == 0)
+#endif
                ber_free_buf( ber );
                return;
        }
 
        /* send BER */
        bytes = send_ldap_ber( conn, ber );
+#ifdef LDAP_CONNECTIONLESS
+       if (conn->c_is_udp == 0)
+#endif
        ber_free_buf( ber );
 
        if ( bytes < 0 ) {
@@ -370,6 +364,12 @@ send_ldap_response(
                return;
        }
 
+#ifdef LDAP_SLAPI
+       slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)err );
+       slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, ( matched != NULL ) ? (void *)ch_strdup( matched ) : NULL );
+       slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, ( text != NULL ) ? (void *)ch_strdup( text ) : NULL );
+#endif /* LDAP_SLAPI */
+
        ldap_pvt_thread_mutex_lock( &num_sent_mutex );
        num_bytes_sent += bytes;
        num_pdu_sent++;
@@ -429,7 +429,7 @@ send_ldap_disconnect(
 }
 
 void
-send_ldap_result(
+slap_send_ldap_result(
     Connection *conn,
     Operation  *op,
     ber_int_t  err,
@@ -447,7 +447,7 @@ send_ldap_result(
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, 
-               "send_ldap_result : conn %lu      op=%lu p=%d\n",
+               "send_ldap_result: conn %lu op=%lu p=%d\n",
                op->o_connid, op->o_opid, op->o_protocol );
 #else
        Debug( LDAP_DEBUG_TRACE,
@@ -482,6 +482,11 @@ send_ldap_result(
        assert( err != LDAP_PARTIAL_RESULTS );
 
        if ( err == LDAP_REFERRAL ) {
+#ifdef LDAP_CONTROL_NOREFERRALS
+               if( op->o_noreferrals ) {
+                       ref = NULL;
+               }
+#endif
                if( ref == NULL ) {
                        err = LDAP_NO_SUCH_OBJECT;
                } else if ( op->o_protocol < LDAP_VERSION3 ) {
@@ -545,7 +550,7 @@ send_ldap_sasl(
 }
 
 void
-send_ldap_extended(
+slap_send_ldap_extended(
     Connection *conn,
     Operation  *op,
     ber_int_t  err,
@@ -567,13 +572,12 @@ send_ldap_extended(
                rspdata != NULL ? rspdata->bv_len : 0 );
 #else
        Debug( LDAP_DEBUG_TRACE,
-               "send_ldap_extended err=%d oid=%s len=%ld\n",
+               "send_ldap_extended: err=%d oid=%s len=%ld\n",
                err,
                rspoid ? rspoid : "",
                rspdata != NULL ? rspdata->bv_len : 0 );
 #endif
 
-
        tag = req2res( op->o_tag );
        msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
 
@@ -582,9 +586,43 @@ send_ldap_extended(
                rspoid, rspdata, NULL, ctrls );
 }
 
+#ifdef LDAP_RES_INTERMEDIATE_RESP
+void
+slap_send_ldap_intermediate_resp(
+       Connection  *conn,
+       Operation   *op,
+       ber_int_t   err,
+       const char  *matched,
+       const char  *text,
+       BerVarray   refs,
+       const char  *rspoid,
+       struct berval *rspdata,
+       LDAPControl **ctrls )
+{
+       ber_tag_t tag;
+       ber_int_t msgid;
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, ENTRY,
+               "send_ldap_intermediate: err=%d oid=%s len=%ld\n",
+               err, rspoid ? rspoid : "",
+               rspdata != NULL ? rspdata->bv_len : 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE,
+               "send_ldap_intermediate: err=%d oid=%s len=%ld\n",
+               err,
+               rspoid ? rspoid : "",
+               rspdata != NULL ? rspdata->bv_len : 0 );
+#endif
+       tag = LDAP_RES_INTERMEDIATE_RESP;
+       msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
+       send_ldap_response( conn, op, tag, msgid,
+               err, matched, text, refs,
+               rspoid, rspdata, NULL, ctrls );
+}
+#endif
 
 void
-send_search_result(
+slap_send_search_result(
     Connection *conn,
     Operation  *op,
     ber_int_t  err,
@@ -662,7 +700,7 @@ send_search_result(
 }
 
 int
-send_search_entry(
+slap_send_search_entry(
     Backend    *be,
     Connection *conn,
     Operation  *op,
@@ -679,8 +717,12 @@ send_search_entry(
        char            *edn;
        int             userattrs;
        int             opattrs;
-       static AccessControlState acl_state_init = ACL_STATE_INIT;
-       AccessControlState acl_state;
+       AccessControlState acl_state = ACL_STATE_INIT;
+#ifdef LDAP_SLAPI
+       /* Support for computed attribute plugins */
+       computed_attr_context    ctx;
+       AttributeName   *anp;
+#endif
 
        AttributeDescription *ad_entry = slap_schema.si_ad_entry;
 
@@ -723,29 +765,19 @@ send_search_entry(
 
        edn = e->e_ndn;
 
+#ifdef LDAP_CONNECTIONLESS
+       if (conn->c_is_udp)
+           ber = op->o_res_ber;
+       else
+#endif
        ber_init_w_nullc( ber, LBER_USE_DER );
 
 #ifdef LDAP_CONNECTIONLESS
-       if (conn->c_is_udp) {
-           rc = ber_write(ber,
-                       (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
-           if (rc != sizeof(struct sockaddr)) {
-#ifdef NEW_LOGGING
-                       LDAP_LOG( OPERATION, ERR, 
-                               "send_search_entry: conn %lu  ber_write failed\n",
-                               conn ? conn->c_connid : 0, 0, 0 );
-#else
-                       Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
-#endif
-                       ber_free_buf( ber );
-                       return( 1 );
-           }
-       }
-       if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
-           rc = ber_printf( ber, "{is{t{O{" /*}}}*/,
-               op->o_msgid, "", LDAP_RES_SEARCH_ENTRY, &e->e_name );
+       if (conn->c_is_udp && conn->c_protocol == LDAP_VERSION2) {
+           rc = ber_printf(ber, "t{0{" /*}}*/,
+               LDAP_RES_SEARCH_ENTRY, &e->e_name);
        } else
-#endif /* LDAP_CONNECTIONLESS */
+#endif
        {
            rc = ber_printf( ber, "{it{O{" /*}}}*/, op->o_msgid,
                LDAP_RES_SEARCH_ENTRY, &e->e_name );
@@ -760,6 +792,9 @@ send_search_entry(
                Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+               if (conn->c_is_udp == 0)
+#endif
                ber_free_buf( ber );
                send_ldap_result( conn, op, LDAP_OTHER,
                    NULL, "encoding DN error", NULL, NULL );
@@ -823,6 +858,9 @@ send_search_entry(
 #else
                        Debug( LDAP_DEBUG_ANY,
                                        "matched values filtering failed\n", 0, 0, 0 );
+#endif
+#ifdef LDAP_CONNECTIONLESS
+                       if (conn->c_is_udp == 0)
 #endif
                                ber_free( ber, 1 );
        
@@ -857,8 +895,6 @@ send_search_entry(
                        }
                }
 
-               acl_state = acl_state_init;
-
                if ( ! access_allowed( be, conn, op, e, desc, NULL,
                        ACL_READ, &acl_state ) )
                {
@@ -883,6 +919,9 @@ send_search_entry(
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+                       if (conn->c_is_udp == 0)
+#endif
                        ber_free_buf( ber );
                        send_ldap_result( conn, op, LDAP_OTHER,
                            NULL, "encoding description error", NULL, NULL );
@@ -923,6 +962,9 @@ send_search_entry(
                                            "ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+                                       if (conn->c_is_udp == 0)
+#endif
                                        ber_free_buf( ber );
                                        send_ldap_result( conn, op, LDAP_OTHER,
                                                NULL, "encoding values error",
@@ -941,6 +983,9 @@ send_search_entry(
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+                       if (conn->c_is_udp == 0)
+#endif
                        ber_free_buf( ber );
                        send_ldap_result( conn, op, LDAP_OTHER,
                            NULL, "encode end error", NULL, NULL );
@@ -1008,6 +1053,9 @@ send_search_entry(
 #else
                                Debug( LDAP_DEBUG_ANY,
                                        "matched values filtering failed\n", 0, 0, 0 );
+#endif
+#ifdef LDAP_CONNECTIONLESS
+                       if (conn->c_is_udp == 0)
 #endif
                                ber_free( ber, 1 );
        
@@ -1042,8 +1090,6 @@ send_search_entry(
                        }
                }
 
-               acl_state = acl_state_init;
-
                if ( ! access_allowed( be, conn, op, e, desc, NULL,
                        ACL_READ, &acl_state ) )
                {
@@ -1071,6 +1117,9 @@ send_search_entry(
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+                       if (conn->c_is_udp == 0)
+#endif
                        ber_free_buf( ber );
                        send_ldap_result( conn, op, LDAP_OTHER,
                            NULL, "encoding description error", NULL, NULL );
@@ -1113,6 +1162,9 @@ send_search_entry(
                                            "ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+                                       if (conn->c_is_udp == 0)
+#endif
                                        ber_free_buf( ber );
                                        send_ldap_result( conn, op, LDAP_OTHER,
                                                NULL, "encoding values error", 
@@ -1133,6 +1185,9 @@ send_search_entry(
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+                       if (conn->c_is_udp == 0)
+#endif
                        ber_free_buf( ber );
                        send_ldap_result( conn, op, LDAP_OTHER,
                            NULL, "encode end error", NULL, NULL );
@@ -1142,6 +1197,45 @@ send_search_entry(
                }
        }
 
+#ifdef LDAP_SLAPI
+       /*
+        * First, setup the computed attribute context that is
+        * passed to all plugins.
+        */
+       ctx.cac_pb = op->o_pb;
+       ctx.cac_attrs = attrs;
+       ctx.cac_attrsonly = attrsonly;
+       ctx.cac_userattrs = userattrs;
+       ctx.cac_opattrs = opattrs;
+       ctx.cac_acl_state = acl_state;
+       ctx.cac_private = (void *)ber;
+
+       /*
+        * For each client requested attribute, call the plugins.
+        */
+       if ( attrs != NULL ) {
+               for ( anp = attrs; anp->an_name.bv_val != NULL; anp++ ) {
+                       rc = compute_evaluator( &ctx, anp->an_name.bv_val, e, slapi_x_compute_output_ber );
+                       if ( rc == 1 ) {
+                               break;
+                       }
+               }
+       } else {
+               /*
+                * Technically we shouldn't be returning operational attributes
+                * when the user requested only user attributes. We'll let the
+                * plugin decide whether to be naughty or not.
+                */
+               rc = compute_evaluator( &ctx, "*", e, slapi_x_compute_output_ber );
+       }
+       if ( rc == 1 ) {
+               ber_free_buf( ber );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "computed attribute error", NULL, NULL );
+               goto error_return;
+       }
+#endif /* LDAP_SLAPI */
+
        /* free e_flags */
        if ( e_flags ) {
                free( e_flags );
@@ -1159,11 +1253,6 @@ send_search_entry(
                rc = ber_printf( ber, /*{*/ "N}" );
        }
 
-#ifdef LDAP_CONNECTIONLESS
-       if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1) {
-               rc = ber_printf( ber, "}" );
-       }
-#endif
        if ( rc == -1 ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( OPERATION, ERR, 
@@ -1173,12 +1262,18 @@ send_search_entry(
                Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+               if (conn->c_is_udp == 0)
+#endif
                ber_free_buf( ber );
                send_ldap_result( conn, op, LDAP_OTHER,
                        NULL, "encode entry end error", NULL, NULL );
                return( 1 );
        }
 
+#ifdef LDAP_CONNECTIONLESS
+       if (conn->c_is_udp == 0) {
+#endif
        bytes = op->o_noop ? 0 : send_ldap_ber( conn, ber );
        ber_free_buf( ber );
 
@@ -1202,6 +1297,10 @@ send_search_entry(
        num_pdu_sent++;
        ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
 
+#ifdef LDAP_CONNECTIONLESS
+       }
+#endif
+
        Statslog( LDAP_DEBUG_STATS2, "conn=%lu op=%lu ENTRY dn=\"%s\"\n",
            conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
 
@@ -1220,7 +1319,7 @@ error_return:;
 }
 
 int
-send_search_reference(
+slap_send_search_reference(
     Backend    *be,
     Connection *conn,
     Operation  *op,
@@ -1238,6 +1337,10 @@ send_search_reference(
        AttributeDescription *ad_ref = slap_schema.si_ad_ref;
        AttributeDescription *ad_entry = slap_schema.si_ad_entry;
 
+       if (op->o_callback && op->o_callback->sc_sendreference) {
+               return op->o_callback->sc_sendreference( be, conn, op, e, refs, ctrls, v2refs );
+       }
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, 
                "send_search_reference: conn %lu  dn=\"%s\"\n", 
@@ -1248,7 +1351,6 @@ send_search_reference(
                e ? e->e_dn : "(null)", 0, 0 );
 #endif
 
-
        if (  e && ! access_allowed( be, conn, op, e,
                ad_entry, NULL, ACL_READ, NULL ) )
        {
@@ -1283,6 +1385,22 @@ send_search_reference(
                return( 1 );
        }
 
+#ifdef LDAP_CONTROL_NOREFERRALS
+       if( op->o_noreferrals ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, ERR, 
+                       "send_search_reference: conn %lu noreferrals control in (%s).\n",
+                       op->o_connid, e->e_dn, 0 );
+#else
+               Debug( LDAP_DEBUG_ANY,
+                       "send_search_reference: noreferrals control in (%s)\n", 
+                       e->e_dn, 0, 0 );
+#endif
+
+               return( 0 );
+       }
+#endif
+
        if( refs == NULL ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( OPERATION, ERR, 
@@ -1306,6 +1424,11 @@ send_search_reference(
                return 0;
        }
 
+#ifdef LDAP_CONNECTIONLESS
+       if (conn->c_is_udp)
+               ber = op->o_res_ber;
+       else
+#endif
        ber_init_w_nullc( ber, LBER_USE_DER );
 
        rc = ber_printf( ber, "{it{W}" /*"}"*/ , op->o_msgid,
@@ -1330,12 +1453,18 @@ send_search_reference(
                        "send_search_reference: ber_printf failed\n", 0, 0, 0 );
 #endif
 
+#ifdef LDAP_CONNECTIONLESS
+               if (conn->c_is_udp == 0)
+#endif
                ber_free_buf( ber );
                send_ldap_result( conn, op, LDAP_OTHER,
                        NULL, "encode DN error", NULL, NULL );
                return -1;
        }
 
+#ifdef LDAP_CONNECTIONLESS
+       if (conn->c_is_udp == 0) {
+#endif
        bytes = op->o_noop ? 0 : send_ldap_ber( conn, ber );
        ber_free_buf( ber );
 
@@ -1344,6 +1473,9 @@ send_search_reference(
        num_refs_sent++;
        num_pdu_sent++;
        ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
+#ifdef LDAP_CONNECTIONLESS
+       }
+#endif
 
        Statslog( LDAP_DEBUG_STATS2, "conn=%lu op=%lu REF dn=\"%s\"\n",
                conn->c_connid, op->o_opid, e ? e->e_dn : "(null)", 0, 0 );
index 312052605ba2cc4458c2073b0b1be220b12929c1..efe9c19ee92d82767a72ef1e75f7e9bf85e193d4 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* root_dse.c - Provides the ROOT DSA-Specific Entry
  *
- * Copyright 1999-2002 The OpenLDAP Foundation.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
 #include "portable.h"
 
 #include <stdio.h>
+
 #include <ac/string.h>
 
 #include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
 #include <ldif.h>
 #include "lber_pvt.h"
 
@@ -134,6 +138,14 @@ root_dse_info(
                        return LDAP_OTHER;
        }
 
+#ifdef LDAP_SLAPI
+       /* netscape supportedExtension */
+       for ( i = 0; (bv = ns_get_supported_extop(i)) != NULL; i++ ) {
+               vals[0] = *bv;
+               attr_merge( e, ad_supportedExtension, vals );
+       }
+#endif /* LDAP_SLAPI */
+
        /* supportedFeatures */
        if( attr_merge( e, ad_supportedFeatures, supportedFeatures ) )
                return LDAP_OTHER;
index dbf768a26d4c01694a573fa3e4c9a36b89388697..355a5c3c0bd8cf4b5c6798f00e9b3088ec2fd840 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
 
 #include "slap.h"
 
-#ifdef HAVE_CYRUS_SASL
 #include <limits.h>
 
-#ifdef HAVE_SASL_SASL_H
-#include <sasl/sasl.h>
-#else
-#include <sasl.h>
-#endif
+#ifdef HAVE_CYRUS_SASL
+# ifdef HAVE_SASL_SASL_H
+#  include <sasl/sasl.h>
+# else
+#  include <sasl.h>
+# endif
+
+# if SASL_VERSION_MAJOR >= 2
+#  include <sasl/saslplug.h>
+#  define      SASL_CONST const
+# else
+#  define      SASL_CONST
+# endif
 
-#include <lutil.h>
-#if SASL_VERSION_MAJOR >= 2
-#include <sasl/saslplug.h>
-#define        SASL_CONST const
-#else
-#define        SASL_CONST
-#endif
+static sasl_security_properties_t sasl_secprops;
+#endif /* HAVE_CYRUS_SASL */
 
 #include "ldap_pvt.h"
 #include "lber_pvt.h"
-
-/* Flags for telling slap_sasl_getdn() what type of identity is being passed */
-#define FLAG_GETDN_AUTHCID 2
-#define FLAG_GETDN_AUTHZID 4
-
-static sasl_security_properties_t sasl_secprops;
+#include <lutil.h>
 
 int slap_sasl_config( int cargc, char **cargv, char *line,
        const char *fname, int lineno )
@@ -49,11 +46,13 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                        if ( cargc != 2 ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: missing policy in \"sasl-authz-policy <policy>\" line\n",
-                                          fname, lineno, 0 );
+                                       "%s: line %d: missing policy in"
+                                       " \"sasl-authz-policy <policy>\" line\n",
+                                       fname, lineno, 0 );
 #else
                                Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: missing policy in \"sasl-authz-policy <policy>\" line\n",
+                                       "%s: line %d: missing policy in"
+                                       " \"sasl-authz-policy <policy>\" line\n",
                                    fname, lineno, 0 );
 #endif
 
@@ -77,18 +76,42 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
 #endif
                                return( 1 );
                        }
-                       
 
+               } else if ( !strcasecmp( cargv[0], "sasl-regexp" ) 
+                       || !strcasecmp( cargv[0], "saslregexp" ) )
+               {
+                       int rc;
+                       if ( cargc != 3 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                       "%s: line %d: need 2 args in "
+                                       "\"saslregexp <match> <replace>\"\n",
+                                       fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY, 
+                                       "%s: line %d: need 2 args in "
+                                       "\"saslregexp <match> <replace>\"\n",
+                                       fname, lineno, 0 );
+#endif
+
+                               return( 1 );
+                       }
+                       rc = slap_sasl_regexp_config( cargv[1], cargv[2] );
+                       if ( rc ) {
+                               return rc;
+                       }
+
+#ifdef HAVE_CYRUS_SASL
                /* set SASL host */
                } else if ( strcasecmp( cargv[0], "sasl-host" ) == 0 ) {
                        if ( cargc < 2 ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: missing host in \"sasl-host <host>\" line\n",
-                                          fname, lineno, 0 );
+                                       "%s: line %d: missing host in \"sasl-host <host>\" line\n",
+                                       fname, lineno, 0 );
 #else
                                Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: missing host in \"sasl-host <host>\" line\n",
+                               "%s: line %d: missing host in \"sasl-host <host>\" line\n",
                                    fname, lineno, 0 );
 #endif
 
@@ -98,8 +121,8 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                        if ( global_host != NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: already set sasl-host!\n",
-                                          fname, lineno, 0 );
+                                       "%s: line %d: already set sasl-host!\n",
+                                       fname, lineno, 0 );
 #else
                                Debug( LDAP_DEBUG_ANY,
                                        "%s: line %d: already set sasl-host!\n",
@@ -116,12 +139,12 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                } else if ( strcasecmp( cargv[0], "sasl-realm" ) == 0 ) {
                        if ( cargc < 2 ) {
 #ifdef NEW_LOGGING
-                               LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: missing realm in \"sasl-realm <realm>\" line.\n",
-                                          fname, lineno, 0 );
+                               LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
+                                       "missing realm in \"sasl-realm <realm>\" line.\n",
+                                       fname, lineno, 0 );
 #else
-                               Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: missing realm in \"sasl-realm <realm>\" line\n",
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "missing realm in \"sasl-realm <realm>\" line.\n",
                                    fname, lineno, 0 );
 #endif
 
@@ -131,8 +154,8 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                        if ( global_realm != NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: already set sasl-realm!\n",
-                                          fname, lineno, 0 );
+                                       "%s: line %d: already set sasl-realm!\n",
+                                       fname, lineno, 0 );
 #else
                                Debug( LDAP_DEBUG_ANY,
                                        "%s: line %d: already set sasl-realm!\n",
@@ -145,42 +168,18 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                                global_realm = ch_strdup( cargv[1] );
                        }
 
-               } else if ( !strcasecmp( cargv[0], "sasl-regexp" ) 
-                       || !strcasecmp( cargv[0], "saslregexp" ) )
-               {
-                       int rc;
-                       if ( cargc != 3 ) {
-#ifdef NEW_LOGGING
-                               LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: need 2 args in "
-                                          "\"saslregexp <match> <replace>\"\n",
-                                          fname, lineno, 0 );
-#else
-                               Debug( LDAP_DEBUG_ANY, 
-                               "%s: line %d: need 2 args in \"saslregexp <match> <replace>\"\n",
-                                   fname, lineno, 0 );
-#endif
-
-                               return( 1 );
-                       }
-                       rc = slap_sasl_regexp_config( cargv[1], cargv[2] );
-                       if ( rc ) {
-                               return rc;
-                       }
-
                /* SASL security properties */
                } else if ( strcasecmp( cargv[0], "sasl-secprops" ) == 0 ) {
                        char *txt;
 
                        if ( cargc < 2 ) {
 #ifdef NEW_LOGGING
-                               LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: missing flags in "
-                                          "\"sasl-secprops <properties>\" line\n",
-                                          fname, lineno, 0 );
+                               LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
+                                       "missing flags in \"sasl-secprops <properties>\" line\n",
+                                       fname, lineno, 0 );
 #else
-                               Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: missing flags in \"sasl-secprops <properties>\" line\n",
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "missing flags in \"sasl-secprops <properties>\" line\n",
                                    fname, lineno, 0 );
 #endif
 
@@ -191,22 +190,25 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                        if ( txt != NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d sasl-secprops: %s\n",
-                                          fname, lineno, txt );
+                                       "%s: line %d sasl-secprops: %s\n",
+                                       fname, lineno, txt );
 #else
                                Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: sasl-secprops: %s\n",
+                                       "%s: line %d: sasl-secprops: %s\n",
                                    fname, lineno, txt );
 #endif
 
                                return 1;
                        }
+#endif /* HAVE_CYRUS_SASL */
            }
 
            return LDAP_SUCCESS;
 }
 
-static int
+#ifdef HAVE_CYRUS_SASL
+
+int
 slap_sasl_log(
        void *context,
        int priority,
@@ -286,190 +288,6 @@ slap_sasl_log(
 }
 
 
-/* Take any sort of identity string and return a DN with the "dn:" prefix. The
-   string returned in *dn is in its own allocated memory, and must be free'd 
-   by the calling process.
-   -Mark Adamson, Carnegie Mellon
-
-   The "dn:" prefix is no longer used anywhere inside slapd. It is only used
-   on strings passed in directly from SASL.
-   -Howard Chu, Symas Corp.
-*/
-
-#define        SET_DN  1
-#define        SET_U   2
-
-static struct berval ext_bv = BER_BVC( "EXTERNAL" );
-
-int slap_sasl_getdn( Connection *conn, char *id, int len,
-       char *user_realm, struct berval *dn, int flags )
-{
-       char *c1;
-       int rc, is_dn = 0, do_norm = 1;
-       sasl_conn_t *ctx;
-       struct berval dn2;
-
-#ifdef NEW_LOGGING
-       LDAP_LOG( TRANSPORT, ENTRY, 
-               "slap_sasl_getdn: conn %d id=%s\n",
-               conn ? conn->c_connid : -1, id ? (*id ? id : "<empty>") : "NULL", 0 );
-#else
-       Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: id=%s\n", 
-      id?(*id?id:"<empty>"):"NULL",0,0 );
-#endif
-
-       dn->bv_val = NULL;
-       dn->bv_len = 0;
-
-       if ( id ) {
-               if ( len == 0 ) len = strlen( id );
-
-               /* Blatantly anonymous ID */
-               if ( len == sizeof("anonymous") - 1 &&
-                       !strcasecmp( id, "anonymous" ) ) {
-                       return( LDAP_SUCCESS );
-               }
-       } else {
-               len = 0;
-       }
-
-       ctx = conn->c_sasl_context;
-
-       /* An authcID needs to be converted to authzID form. Set the
-        * values directly into *dn; they will be normalized later. (and
-        * normalizing always makes a new copy.) An ID from a TLS certificate
-        * is already normalized, so copy it and skip normalization.
-        */
-       if( flags & FLAG_GETDN_AUTHCID ) {
-#ifdef HAVE_TLS
-               if( conn->c_is_tls &&
-                       conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len &&
-                       strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 )
-               {
-                       /* X.509 DN is already normalized */
-                       do_norm = 0;
-                       is_dn = SET_DN;
-                       ber_str2bv( id, len, 1, dn );
-
-               } else
-#endif
-               {
-                       /* convert to u:<username> form */
-                       is_dn = SET_U;
-                       dn->bv_val = id;
-                       dn->bv_len = len;
-               }
-       }
-       if( !is_dn ) {
-               if( !strncasecmp( id, "u:", sizeof("u:")-1 )) {
-                       is_dn = SET_U;
-                       dn->bv_val = id+2;
-                       dn->bv_len = len-2;
-               } else if ( !strncasecmp( id, "dn:", sizeof("dn:")-1) ) {
-                       is_dn = SET_DN;
-                       dn->bv_val = id+3;
-                       dn->bv_len = len-3;
-               }
-       }
-
-       /* No other possibilities from here */
-       if( !is_dn ) {
-               dn->bv_val = NULL;
-               dn->bv_len = 0;
-               return( LDAP_INAPPROPRIATE_AUTH );
-       }
-
-       /* Username strings */
-       if( is_dn == SET_U ) {
-               char *p, *realm;
-               len = dn->bv_len + sizeof("uid=")-1 + sizeof(",cn=auth")-1;
-
-               /* username may have embedded realm name */
-               if( ( realm = strchr( dn->bv_val, '@') ) ) {
-                       *realm++ = '\0';
-                       len += sizeof(",cn=")-2;
-               } else if( user_realm && *user_realm ) {
-                       len += strlen( user_realm ) + sizeof(",cn=")-1;
-               }
-
-               if( conn->c_sasl_bind_mech.bv_len ) {
-                       len += conn->c_sasl_bind_mech.bv_len + sizeof(",cn=")-1;
-               }
-
-               /* Build the new dn */
-               c1 = dn->bv_val;
-               dn->bv_val = SLAP_MALLOC( len+1 );
-               if( dn->bv_val == NULL ) {
-#ifdef NEW_LOGGING
-                       LDAP_LOG( TRANSPORT, ERR, 
-                               "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
-#else
-                       Debug( LDAP_DEBUG_ANY, 
-                               "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
-#endif
-                       return LDAP_OTHER;
-               }
-               p = lutil_strcopy( dn->bv_val, "uid=" );
-               p = lutil_strncopy( p, c1, dn->bv_len );
-
-               if( realm ) {
-                       int rlen = dn->bv_len - ( realm - c1 );
-                       p = lutil_strcopy( p, ",cn=" );
-                       p = lutil_strncopy( p, realm, rlen );
-                       realm[-1] = '@';
-               } else if( user_realm && *user_realm ) {
-                       p = lutil_strcopy( p, ",cn=" );
-                       p = lutil_strcopy( p, user_realm );
-               }
-
-               if( conn->c_sasl_bind_mech.bv_len ) {
-                       p = lutil_strcopy( p, ",cn=" );
-                       p = lutil_strcopy( p, conn->c_sasl_bind_mech.bv_val );
-               }
-               p = lutil_strcopy( p, ",cn=auth" );
-               dn->bv_len = p - dn->bv_val;
-
-#ifdef NEW_LOGGING
-               LDAP_LOG( TRANSPORT, ENTRY, 
-                       "slap_sasl_getdn: u:id converted to %s.\n", dn->bv_val, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE, "getdn: u:id converted to %s\n", dn->bv_val,0,0 );
-#endif
-       }
-
-       /* All strings are in DN form now. Normalize if needed. */
-       if ( do_norm ) {
-               rc = dnNormalize2( NULL, dn, &dn2 );
-
-               /* User DNs were constructed above and must be freed now */
-               if ( is_dn == SET_U )
-                       ch_free( dn->bv_val );
-
-               if ( rc != LDAP_SUCCESS ) {
-                       dn->bv_val = NULL;
-                       dn->bv_len = 0;
-                       return rc;
-               }
-               *dn = dn2;
-       }
-
-       /* Run thru regexp */
-       slap_sasl2dn( conn, dn, &dn2 );
-       if( dn2.bv_val ) {
-               ch_free( dn->bv_val );
-               *dn = dn2;
-#ifdef NEW_LOGGING
-               LDAP_LOG( TRANSPORT, ENTRY, 
-                       "slap_sasl_getdn: dn:id converted to %s.\n", dn->bv_val, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE, "getdn: dn:id converted to %s\n",
-                       dn->bv_val, 0, 0 );
-#endif
-       }
-
-       return( LDAP_SUCCESS );
-}
-
 #if SASL_VERSION_MAJOR >= 2
 static const char *slap_propnames[] = {
        "*slapConn", "*authcDN", "*authzDN", NULL };
@@ -607,7 +425,7 @@ slap_auxprop_lookup(
                Backend *be;
                Operation op = {0};
                slap_callback cb = { slap_cb_null_response,
-                       slap_cb_null_sresult, sasl_ap_lookup, NULL };
+                       slap_cb_null_sresult, sasl_ap_lookup, slap_cb_null_sreference, NULL };
 
                cb.sc_private = &sl;
 
@@ -714,7 +532,7 @@ slap_sasl_checkpass(
         */
 
        rc = slap_sasl_getdn( conn, (char *)username, 0, NULL, &dn,
-               FLAG_GETDN_AUTHCID );
+               SLAP_GETDN_AUTHCID );
        if ( rc != LDAP_SUCCESS ) {
                sasl_seterror( sconn, 0, ldap_err2string( rc ) );
                return SASL_NOUSER;
@@ -733,7 +551,7 @@ slap_sasl_checkpass(
        if ( be && be->be_search ) {
                Operation op = {0};
                slap_callback cb = { slap_cb_null_response,
-                       slap_cb_null_sresult, sasl_cb_checkpass, NULL };
+                       slap_cb_null_sresult, sasl_cb_checkpass, slap_cb_null_sreference, NULL };
 
                ci.cred.bv_val = (char *)pass;
                ci.cred.bv_len = passlen;
@@ -792,13 +610,13 @@ slap_sasl_canonicalize(
        LDAP_LOG( TRANSPORT, ENTRY, 
                "slap_sasl_canonicalize: conn %d %s=\"%s\"\n",
                conn ? conn->c_connid : -1,
-               (flags & SASL_CU_AUTHID) ? "authcid" : "authzid", in ? in : "<empty>");
+               (flags & SASL_CU_AUTHID) ? "authcid" : "authzid",
+               in ? in : "<empty>");
 #else
-       Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: "
-               "%s=\"%s\"\n",
-                       conn ? conn->c_connid : -1,
-                       (flags & SASL_CU_AUTHID) ? "authcid" : "authzid",
-                       in ? in : "<empty>" );
+       Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: %s=\"%s\"\n",
+               conn ? conn->c_connid : -1,
+               (flags & SASL_CU_AUTHID) ? "authcid" : "authzid",
+               in ? in : "<empty>");
 #endif
 
        /* If name is too big, just truncate. We don't care, we're
@@ -853,7 +671,7 @@ slap_sasl_canonicalize(
        }
 
        rc = slap_sasl_getdn( conn, (char *)in, inlen, (char *)user_realm, &dn,
-               (flags & SASL_CU_AUTHID) ? FLAG_GETDN_AUTHCID : FLAG_GETDN_AUTHZID );
+               (flags & SASL_CU_AUTHID) ? SLAP_GETDN_AUTHCID : SLAP_GETDN_AUTHZID );
        if ( rc != LDAP_SUCCESS ) {
                sasl_seterror( sconn, 0, ldap_err2string( rc ) );
                return SASL_NOAUTHZ;
@@ -867,14 +685,16 @@ slap_sasl_canonicalize(
 #ifdef NEW_LOGGING
        LDAP_LOG( TRANSPORT, ENTRY, 
                "slap_sasl_canonicalize: conn %d %s=\"%s\"\n",
-               conn ? conn->c_connid : -1, names[0]+1, dn.bv_val );
+               conn ? conn->c_connid : -1, names[0]+1,
+               dn.bv_val ? dn.bv_val : "<EMPTY>" );
 #else
-       Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: "
-               "%s=\"%s\"\n",
-                       conn ? conn->c_connid : -1,
-                       names[0]+1, dn.bv_val );
+       Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: %s=\"%s\"\n",
+               conn ? conn->c_connid : -1, names[0]+1,
+               dn.bv_val ? dn.bv_val : "<EMPTY>" );
 #endif
-done:  AC_MEMCPY( out, in, inlen );
+
+done:
+       AC_MEMCPY( out, in, inlen );
        out[inlen] = '\0';
 
        *out_len = inlen;
@@ -1015,7 +835,8 @@ slap_sasl_authorize(
 
        /* Convert the identities to DN's. If no authzid was given, client will
           be bound as the DN matching their username */
-       rc = slap_sasl_getdn( conn, (char *)authcid, 0, realm, &authcDN, FLAG_GETDN_AUTHCID );
+       rc = slap_sasl_getdn( conn, (char *)authcid, 0, realm,
+               &authcDN, SLAP_GETDN_AUTHCID );
        if( rc != LDAP_SUCCESS ) {
                *errstr = ldap_err2string( rc );
                return SASL_NOAUTHZ;
@@ -1033,7 +854,8 @@ slap_sasl_authorize(
                conn->c_sasl_dn = authcDN;
                goto ok;
        }
-       rc = slap_sasl_getdn( conn, (char *)authzid, 0, realm, &authzDN, FLAG_GETDN_AUTHZID );
+       rc = slap_sasl_getdn( conn, (char *)authzid, 0, realm,
+               &authzDN, SLAP_GETDN_AUTHZID );
        if( rc != LDAP_SUCCESS ) {
                ch_free( authcDN.bv_val );
                *errstr = ldap_err2string( rc );
@@ -1119,7 +941,6 @@ slap_sasl_err2ldap( int saslerr )
 }
 #endif
 
-
 int slap_sasl_init( void )
 {
 #ifdef HAVE_CYRUS_SASL
@@ -1695,4 +1516,188 @@ slap_sasl_setpass(
 done:
        return rc;
 }
+#endif /* HAVE_CYRUS_SASL */
+
+/* Take any sort of identity string and return a DN with the "dn:" prefix. The
+   string returned in *dn is in its own allocated memory, and must be free'd 
+   by the calling process.
+   -Mark Adamson, Carnegie Mellon
+
+   The "dn:" prefix is no longer used anywhere inside slapd. It is only used
+   on strings passed in directly from SASL.
+   -Howard Chu, Symas Corp.
+*/
+
+#define SET_NONE       0
+#define        SET_DN          1
+#define        SET_U           2
+
+static struct berval ext_bv = BER_BVC( "EXTERNAL" );
+
+int slap_sasl_getdn( Connection *conn, char *id, int len,
+       char *user_realm, struct berval *dn, int flags )
+{
+       char *c1;
+       int rc, is_dn = SET_NONE, do_norm = 1;
+       struct berval dn2;
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "slap_sasl_getdn: conn %d id=%s [len=%d]\n",
+               conn ? conn->c_connid : -1, id ? (*id ? id : "<empty>") : "NULL", len );
+#else
+       Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: id=%s [len=%d]\n", 
+               id ? ( *id ? id : "<empty>" ) : "NULL", len, 0 );
 #endif
+
+       dn->bv_val = NULL;
+       dn->bv_len = 0;
+
+       if ( id ) {
+               if ( len == 0 ) len = strlen( id );
+
+               /* Blatantly anonymous ID */
+               if ( len == sizeof("anonymous") - 1 &&
+                       !strcasecmp( id, "anonymous" ) ) {
+                       return( LDAP_SUCCESS );
+               }
+       } else {
+               len = 0;
+       }
+
+       /* An authcID needs to be converted to authzID form. Set the
+        * values directly into *dn; they will be normalized later. (and
+        * normalizing always makes a new copy.) An ID from a TLS certificate
+        * is already normalized, so copy it and skip normalization.
+        */
+       if( flags & SLAP_GETDN_AUTHCID ) {
+               if( conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len &&
+                       strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 )
+               {
+                       /* EXTERNAL DNs are already normalized */
+                       do_norm = 0;
+                       is_dn = SET_DN;
+                       ber_str2bv( id, len, 1, dn );
+
+               } else {
+                       /* convert to u:<username> form */
+                       is_dn = SET_U;
+                       dn->bv_val = id;
+                       dn->bv_len = len;
+               }
+       }
+       if( is_dn == SET_NONE ) {
+               if( !strncasecmp( id, "u:", sizeof("u:")-1 )) {
+                       is_dn = SET_U;
+                       dn->bv_val = id+2;
+                       dn->bv_len = len-2;
+               } else if ( !strncasecmp( id, "dn:", sizeof("dn:")-1) ) {
+                       is_dn = SET_DN;
+                       dn->bv_val = id+3;
+                       dn->bv_len = len-3;
+               }
+       }
+
+       /* No other possibilities from here */
+       if( is_dn == SET_NONE ) {
+               dn->bv_val = NULL;
+               dn->bv_len = 0;
+               return( LDAP_INAPPROPRIATE_AUTH );
+       }
+
+       /* Username strings */
+       if( is_dn == SET_U ) {
+               char *p, *realm;
+               len = dn->bv_len + sizeof("uid=")-1 + sizeof(",cn=auth")-1;
+
+               /* username may have embedded realm name */
+               if( ( realm = strchr( dn->bv_val, '@') ) ) {
+                       *realm++ = '\0';
+                       len += sizeof(",cn=")-2;
+               } else if( user_realm && *user_realm ) {
+                       len += strlen( user_realm ) + sizeof(",cn=")-1;
+               }
+
+               if( conn->c_sasl_bind_mech.bv_len ) {
+                       len += conn->c_sasl_bind_mech.bv_len + sizeof(",cn=")-1;
+               }
+
+               /* Build the new dn */
+               c1 = dn->bv_val;
+               dn->bv_val = SLAP_MALLOC( len+1 );
+               if( dn->bv_val == NULL ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( TRANSPORT, ERR, 
+                               "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, 
+                               "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
+#endif
+                       return LDAP_OTHER;
+               }
+               p = lutil_strcopy( dn->bv_val, "uid=" );
+               p = lutil_strncopy( p, c1, dn->bv_len );
+
+               if( realm ) {
+                       int rlen = dn->bv_len - ( realm - c1 );
+                       p = lutil_strcopy( p, ",cn=" );
+                       p = lutil_strncopy( p, realm, rlen );
+                       realm[-1] = '@';
+               } else if( user_realm && *user_realm ) {
+                       p = lutil_strcopy( p, ",cn=" );
+                       p = lutil_strcopy( p, user_realm );
+               }
+
+               if( conn->c_sasl_bind_mech.bv_len ) {
+                       p = lutil_strcopy( p, ",cn=" );
+                       p = lutil_strcopy( p, conn->c_sasl_bind_mech.bv_val );
+               }
+               p = lutil_strcopy( p, ",cn=auth" );
+               dn->bv_len = p - dn->bv_val;
+
+#ifdef NEW_LOGGING
+               LDAP_LOG( TRANSPORT, ENTRY, 
+                       "slap_sasl_getdn: u:id converted to %s.\n", dn->bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "getdn: u:id converted to %s\n", dn->bv_val,0,0 );
+#endif
+       } else {
+               
+               /* Dup the DN in any case, so we don't risk 
+                * leaks or dangling pointers later,
+                * and the DN value is '\0' terminated */
+               ber_dupbv( &dn2, dn );
+               dn->bv_val = dn2.bv_val;
+       }
+
+       /* All strings are in DN form now. Normalize if needed. */
+       if ( do_norm ) {
+               rc = dnNormalize2( NULL, dn, &dn2 );
+
+               /* User DNs were constructed above and must be freed now */
+               ch_free( dn->bv_val );
+
+               if ( rc != LDAP_SUCCESS ) {
+                       dn->bv_val = NULL;
+                       dn->bv_len = 0;
+                       return rc;
+               }
+               *dn = dn2;
+       }
+
+       /* Run thru regexp */
+       slap_sasl2dn( conn, dn, &dn2 );
+       if( dn2.bv_val ) {
+               ch_free( dn->bv_val );
+               *dn = dn2;
+#ifdef NEW_LOGGING
+               LDAP_LOG( TRANSPORT, ENTRY, 
+                       "slap_sasl_getdn: dn:id converted to %s.\n", dn->bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "getdn: dn:id converted to %s\n",
+                       dn->bv_val, 0, 0 );
+#endif
+       }
+
+       return( LDAP_SUCCESS );
+}
index da04c74e967b47a09c6e49e9a7f48168dd173eae..75007d86f4d6d78358e1d4a84720db9bd2f1b10e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
 
 #include "slap.h"
 
-#ifdef HAVE_CYRUS_SASL
 #include <limits.h>
 
-#ifdef HAVE_SASL_SASL_H
-#include <sasl/sasl.h>
-#else
-#include <sasl.h>
-#endif
-
 #include <ldap_pvt.h>
 
 #define SASLREGEX_REPLACE 10
@@ -348,6 +341,12 @@ void slap_cb_null_sresult( Connection *conn, Operation *o, ber_int_t err,
 {
 }
 
+int slap_cb_null_sreference( BackendDB *db, Connection *conn, Operation *o, 
+       Entry *e, BerVarray r, LDAPControl **c, BerVarray *v2)
+{
+       return 0;
+}
+
 /* This callback actually does some work...*/
 static int sasl_sc_sasl2dn( BackendDB *be, Connection *conn, Operation *o,
        Entry *e, AttributeName *an, int ao, LDAPControl **c)
@@ -360,8 +359,8 @@ static int sasl_sc_sasl2dn( BackendDB *be, Connection *conn, Operation *o,
                ndn->bv_val = NULL;
 
 #ifdef NEW_LOGGING
-       LDAP_LOG( TRANSPORT, DETAIL1,
-                   "slap_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
+               LDAP_LOG( TRANSPORT, DETAIL1,
+                       "slap_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
                        "slap_sasl2dn: search DN returned more than 1 entry\n", 0,0,0 );
@@ -373,108 +372,6 @@ static int sasl_sc_sasl2dn( BackendDB *be, Connection *conn, Operation *o,
        return 0;
 }
 
-/*
- * Given a SASL name (e.g. "UID=name,cn=REALM,cn=MECH,cn=AUTH")
- * return the LDAP DN to which it matches. The SASL regexp rules in the config
- * file turn the SASL name into an LDAP URI. If the URI is just a DN (or a
- * search with scope=base), just return the URI (or its searchbase). Otherwise
- * an internal search must be done, and if that search returns exactly one
- * entry, return the DN of that one entry.
- */
-
-void slap_sasl2dn( Connection *conn,
-       struct berval *saslname, struct berval *sasldn )
-{
-       int rc;
-       Backend *be = NULL;
-       struct berval dn = { 0, NULL };
-       int scope = LDAP_SCOPE_BASE;
-       Filter *filter = NULL;
-       slap_callback cb = {slap_cb_null_response, slap_cb_null_sresult, sasl_sc_sasl2dn, NULL};
-       Operation op = {0};
-       struct berval regout = { 0, NULL };
-
-#ifdef NEW_LOGGING
-       LDAP_LOG( TRANSPORT, ENTRY, 
-               "slap_sasl2dn: converting SASL name %s to DN.\n",
-               saslname->bv_val, 0, 0 );
-#else
-       Debug( LDAP_DEBUG_TRACE, "==>slap_sasl2dn: "
-               "converting SASL name %s to a DN\n",
-               saslname->bv_val, 0,0 );
-#endif
-
-       sasldn->bv_val = NULL;
-       sasldn->bv_len = 0;
-       cb.sc_private = sasldn;
-
-       /* Convert the SASL name into a minimal URI */
-       if( !slap_sasl_regexp( saslname, &regout ) ) {
-               goto FINISHED;
-       }
-
-       rc = slap_parseURI( &regout, &dn, &scope, &filter );
-       if( regout.bv_val ) ch_free( regout.bv_val );
-       if( rc != LDAP_SUCCESS ) {
-               goto FINISHED;
-       }
-
-       /* Must do an internal search */
-       be = select_backend( &dn, 0, 1 );
-
-       /* Massive shortcut: search scope == base */
-       if( scope == LDAP_SCOPE_BASE ) {
-               *sasldn = dn;
-               dn.bv_len = 0;
-               dn.bv_val = NULL;
-               goto FINISHED;
-       }
-
-#ifdef NEW_LOGGING
-       LDAP_LOG( TRANSPORT, DETAIL1, 
-               "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
-               dn.bv_val, scope, 0 );
-#else
-       Debug( LDAP_DEBUG_TRACE,
-               "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
-               dn.bv_val, scope, 0 );
-#endif
-
-       if(( be == NULL ) || ( be->be_search == NULL)) {
-               goto FINISHED;
-       }
-       suffix_alias( be, &dn );
-
-       op.o_tag = LDAP_REQ_SEARCH;
-       op.o_protocol = LDAP_VERSION3;
-       op.o_ndn = *saslname;
-       op.o_callback = &cb;
-       op.o_time = slap_get_time();
-       op.o_do_not_cache = 1;
-       op.o_threadctx = conn->c_sasl_bindop->o_threadctx;
-
-       (*be->be_search)( be, conn, &op, NULL, &dn,
-               scope, LDAP_DEREF_NEVER, 1, 0,
-               filter, NULL, NULL, 1 );
-       
-FINISHED:
-       if( sasldn->bv_len ) {
-               conn->c_authz_backend = be;
-       }
-       if( dn.bv_len ) ch_free( dn.bv_val );
-       if( filter ) filter_free( filter );
-
-#ifdef NEW_LOGGING
-       LDAP_LOG( TRANSPORT, ENTRY, 
-               "slap_sasl2dn: Converted SASL name to %s\n",
-               sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
-#else
-       Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n",
-               sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
-#endif
-
-       return;
-}
 
 typedef struct smatch_info {
        struct berval *dn;
@@ -512,7 +409,12 @@ int slap_sasl_match(Connection *conn, struct berval *rule, struct berval *assert
        Filter *filter=NULL;
        regex_t reg;
        smatch_info sm;
-       slap_callback cb = { slap_cb_null_response, slap_cb_null_sresult, sasl_sc_smatch, NULL };
+       slap_callback cb = {
+               slap_cb_null_response,
+               slap_cb_null_sresult,
+               sasl_sc_smatch,
+               NULL
+       };
        Operation op = {0};
 
 #ifdef NEW_LOGGING
@@ -655,7 +557,109 @@ COMPLETE:
 
        return( rc );
 }
-#endif /* HAVE_CYRUS_SASL */
+
+/*
+ * Given a SASL name (e.g. "UID=name,cn=REALM,cn=MECH,cn=AUTH")
+ * return the LDAP DN to which it matches. The SASL regexp rules in the config
+ * file turn the SASL name into an LDAP URI. If the URI is just a DN (or a
+ * search with scope=base), just return the URI (or its searchbase). Otherwise
+ * an internal search must be done, and if that search returns exactly one
+ * entry, return the DN of that one entry.
+ */
+void slap_sasl2dn( Connection *conn,
+       struct berval *saslname, struct berval *sasldn )
+{
+       int rc;
+       Backend *be = NULL;
+       struct berval dn = { 0, NULL };
+       int scope = LDAP_SCOPE_BASE;
+       Filter *filter = NULL;
+       slap_callback cb = { slap_cb_null_response,
+               slap_cb_null_sresult, sasl_sc_sasl2dn, slap_cb_null_sreference, NULL};
+       Operation op = {0};
+       struct berval regout = { 0, NULL };
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "slap_sasl2dn: converting SASL name %s to DN.\n",
+               saslname->bv_val, 0, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, "==>slap_sasl2dn: "
+               "converting SASL name %s to a DN\n",
+               saslname->bv_val, 0,0 );
+#endif
+
+       sasldn->bv_val = NULL;
+       sasldn->bv_len = 0;
+       cb.sc_private = sasldn;
+
+       /* Convert the SASL name into a minimal URI */
+       if( !slap_sasl_regexp( saslname, &regout ) ) {
+               goto FINISHED;
+       }
+
+       rc = slap_parseURI( &regout, &dn, &scope, &filter );
+       if( regout.bv_val ) ch_free( regout.bv_val );
+       if( rc != LDAP_SUCCESS ) {
+               goto FINISHED;
+       }
+
+       /* Must do an internal search */
+       be = select_backend( &dn, 0, 1 );
+
+       /* Massive shortcut: search scope == base */
+       if( scope == LDAP_SCOPE_BASE ) {
+               *sasldn = dn;
+               dn.bv_len = 0;
+               dn.bv_val = NULL;
+               goto FINISHED;
+       }
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( TRANSPORT, DETAIL1, 
+               "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
+               dn.bv_val, scope, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE,
+               "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
+               dn.bv_val, scope, 0 );
+#endif
+
+       if(( be == NULL ) || ( be->be_search == NULL)) {
+               goto FINISHED;
+       }
+       suffix_alias( be, &dn );
+
+       op.o_tag = LDAP_REQ_SEARCH;
+       op.o_protocol = LDAP_VERSION3;
+       op.o_ndn = conn->c_ndn;
+       op.o_callback = &cb;
+       op.o_time = slap_get_time();
+       op.o_do_not_cache = 1;
+       op.o_threadctx = conn->c_sasl_bindop->o_threadctx;
+
+       (*be->be_search)( be, conn, &op, NULL, &dn,
+               scope, LDAP_DEREF_NEVER, 1, 0,
+               filter, NULL, NULL, 1 );
+       
+FINISHED:
+       if( sasldn->bv_len ) {
+               conn->c_authz_backend = be;
+       }
+       if( dn.bv_len ) ch_free( dn.bv_val );
+       if( filter ) filter_free( filter );
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "slap_sasl2dn: Converted SASL name to %s\n",
+               sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n",
+               sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
+#endif
+
+       return;
+}
 
 
 /* Check if a bind can SASL authorize to another identity.
@@ -667,7 +671,6 @@ int slap_sasl_authorized( Connection *conn,
 {
        int rc = LDAP_INAPPROPRIATE_AUTH;
 
-#ifdef HAVE_CYRUS_SASL
        /* User binding as anonymous */
        if ( authzDN == NULL ) {
                rc = LDAP_SUCCESS;
@@ -680,7 +683,8 @@ int slap_sasl_authorized( Connection *conn,
                authcDN->bv_val, authzDN->bv_val, 0 );
 #else
        Debug( LDAP_DEBUG_TRACE,
-          "==>slap_sasl_authorized: can %s become %s?\n", authcDN->bv_val, authzDN->bv_val, 0 );
+          "==>slap_sasl_authorized: can %s become %s?\n",
+               authcDN->bv_val, authzDN->bv_val, 0 );
 #endif
 
        /* If person is authorizing to self, succeed */
@@ -689,6 +693,12 @@ int slap_sasl_authorized( Connection *conn,
                goto DONE;
        }
 
+       /* Allow the manager to authorize as any DN. */
+       if( be_isroot( conn->c_authz_backend, authcDN )) {
+               rc = LDAP_SUCCESS;
+               goto DONE;
+       }
+
        /* Check source rules */
        if( authz_policy & SASL_AUTHZ_TO ) {
                rc = slap_sasl_check_authz( conn, authcDN, authzDN,
@@ -710,7 +720,6 @@ int slap_sasl_authorized( Connection *conn,
        rc = LDAP_INAPPROPRIATE_AUTH;
 
 DONE:
-#endif
 
 #ifdef NEW_LOGGING
        LDAP_LOG( TRANSPORT, RESULTS, "slap_sasl_authorized: return %d\n", rc,0,0 );
index 313668a4cbb407b4dcf5056c2f17bf6f4c939610..d2fb876ba7f7ac911fd1b81d386ed14300f2f057 100644 (file)
@@ -1,7 +1,7 @@
 /* schema_check.c - routines to enforce schema definitions */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -52,11 +52,9 @@ entry_schema_check(
        int subentry = is_entry_subentry( e );
        int collectiveSubentry = 0;
 
-#if 0
        if( subentry ) {
                collectiveSubentry = is_entry_collectiveAttributeSubentry( e );
        }
-#endif
 
        *text = textbuf;
 
@@ -214,11 +212,59 @@ entry_schema_check(
 
        } else if ( sc != oc ) {
                snprintf( textbuf, textlen, 
-                       "structural object class modification from '%s' to '%s' not allowed",
+                       "structural object class modification "
+                       "from '%s' to '%s' not allowed",
                        asc->a_vals[0].bv_val, nsc.bv_val );
                return LDAP_NO_OBJECT_CLASS_MODS;
        }
 
+       {       /* naming check */
+               LDAPRDN *rdn;
+               const char *p;
+               ber_len_t cnt;
+
+               /*
+                * Get attribute type(s) and attribute value(s) of our RDN
+                */
+               if ( ldap_bv2rdn( &e->e_name, &rdn, (char **)&p,
+                       LDAP_DN_FORMAT_LDAP ) )
+               {
+                       *text = "unrecongized attribute type(s) in RDN";
+                       return LDAP_INVALID_DN_SYNTAX;
+               }
+
+               /* Check that each AVA of the RDN is present in the entry */
+               /* FIXME: Should also check that each AVA lists a distinct type */
+               for ( cnt = 0; rdn[0][cnt]; cnt++ ) {
+                       LDAPAVA *ava = rdn[0][cnt];
+                       AttributeDescription *desc = NULL;
+                       Attribute *attr;
+                       const char *errtext;
+
+                       rc = slap_bv2ad( &ava->la_attr, &desc, &errtext );
+                       if ( rc != LDAP_SUCCESS ) {
+                               snprintf( textbuf, textlen, "%s (in RDN)", errtext );
+                               return rc;
+                       }
+
+                       /* find the naming attribute */
+                       attr = attr_find( e->e_attrs, desc );
+                       if ( attr == NULL ) {
+                               snprintf( textbuf, textlen, 
+                                       "naming attribute '%s' is not present in entry",
+                                       ava->la_attr );
+                               return LDAP_NO_SUCH_ATTRIBUTE;
+                       }
+
+                       if ( value_find( desc, attr->a_vals, &ava->la_value ) != 0 ) {
+                               snprintf( textbuf, textlen, 
+                                       "value of naming attribute '%s' is not present in entry",
+                                       ava->la_attr );
+                               return LDAP_NO_SUCH_ATTRIBUTE;
+                       }
+               }
+       }
+
 #ifdef SLAP_EXTENDED_SCHEMA
        /* find the content rule for the structural class */
        cr = cr_find( sc->soc_oid );
index 532e33b8c4c82ae16027260dc17d310790324145..12d0d5d324f1d5a8c824ec233a7015ad4c4cee33 100644 (file)
@@ -1,7 +1,7 @@
 /* schema_init.c - init builtin schema */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -3506,7 +3506,7 @@ integerBitAndMatch(
        long lValue, lAssertedValue;
 
        /* safe to assume integers are NUL terminated? */
-       lValue = strtoul(value->bv_val, NULL, 10);
+       lValue = strtol(value->bv_val, NULL, 10);
        if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
                return LDAP_CONSTRAINT_VIOLATION;
        }
@@ -3534,7 +3534,7 @@ integerBitOrMatch(
        long lValue, lAssertedValue;
 
        /* safe to assume integers are NUL terminated? */
-       lValue = strtoul(value->bv_val, NULL, 10);
+       lValue = strtol(value->bv_val, NULL, 10);
        if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
                return LDAP_CONSTRAINT_VIOLATION;
        }
index 2cea01e1d9bbf47fe24e60917fbf1eff1d8adde3..85c4f80a09d77799331ae993e95941c9f79c62d3 100644 (file)
@@ -1,7 +1,7 @@
 /* schema_init.c - init builtin schema */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -320,6 +320,20 @@ static struct slap_schema_oc_map {
                "MUST cn )",
                0, SLAP_OC_OPERATIONAL,
                offsetof(struct slap_internal_schema, si_oc_monitor) },
+#ifdef LDAP_DEVEL
+       { "collectiveAttributeSubentry", "( 2.5.17.2 "
+                       "NAME 'collectiveAttributeSubentry' "
+                       "AUXILIARY )",
+               subentryObjectClass,
+               SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
+               offsetof(struct slap_internal_schema, si_oc_collectiveAttributeSubentry) },
+       { "dynamicObject", "( 1.3.6.1.4.1.1466.101.119.2 "
+                       "NAME 'dynamicObject' "
+                       "DESC 'RFC2589: Dynamic Object' "
+                       "SUP top AUXILIARY )",
+               dynamicObjectClass, SLAP_OC_DYNAMICOBJECT,
+               offsetof(struct slap_internal_schema, si_oc_dynamicObject) },
+#endif
        { NULL, NULL, NULL, 0, 0 }
 };
 
@@ -411,6 +425,23 @@ static struct slap_schema_ad_map {
                NULL, 0,
                NULL, NULL, NULL, NULL, NULL,
                offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
+#ifdef LDAP_DEVEL
+       { "collectiveAttributeSubentries", "( 2.5.18.12 "
+                       "NAME 'collectiveAttributeSubentries' "
+                       "EQUALITY distinguishedNameMatch "
+                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
+                       "NO-USER-MODIFICATION USAGE directoryOperation )",
+               NULL, SLAP_AT_HIDE,
+               NULL, NULL, NULL, NULL, NULL,
+               offsetof(struct slap_internal_schema, si_ad_collectiveSubentries) },
+       { "collectiveExclusions", "( 2.5.18.7 NAME 'collectiveExclusions' "
+                       "EQUALITY objectIdentifierMatch "
+                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
+                       "USAGE directoryOperation )",
+               NULL, SLAP_AT_HIDE,
+               NULL, NULL, NULL, NULL, NULL,
+               offsetof(struct slap_internal_schema, si_ad_collectiveExclusions) },
+#endif
 
        { "entryUUID", "( 1.3.6.1.4.1.4203.666.1.6 NAME 'entryUUID' "   
                        "DESC 'LCUP/LDUP: UUID of the entry' "
@@ -660,6 +691,24 @@ static struct slap_schema_ad_map {
                offsetof(struct slap_internal_schema, si_ad_aci) },
 #endif
 
+#ifdef LDAP_DEVEL
+       { "entryTtl", "( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTtl' "
+                       "DESC 'RFC2589: entry time-to-live' "
+                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE "
+                       "NO-USER-MODIFICATION USAGE dSAOperation )",
+               dynamicAttribute, 0,
+               NULL, NULL, NULL, NULL, NULL,
+               offsetof(struct slap_internal_schema, si_ad_entryTtl) },
+       { "dynamicSubtrees", "( 1.3.6.1.4.1.1466.101.119.4 "
+                       "NAME 'dynamicSubtrees' "
+                       "DESC 'RFC2589: dynamic subtrees' "
+                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION "
+                       "USAGE dSAOperation )",
+               rootDseAttribute, 0,
+               NULL, NULL, NULL, NULL, NULL,
+               offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) },
+#endif
+
        /* userApplication attributes (which system schema depends upon) */
        { "distinguishedName", "( 2.5.4.49 NAME 'distinguishedName' "
                        "DESC 'RFC2256: common supertype of DN attributes' "
@@ -721,13 +770,13 @@ static struct slap_schema_ad_map {
                offsetof(struct slap_internal_schema, si_ad_krbName) },
 #endif
 
-       { NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
+       { NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0 }
 };
 
 static AttributeType slap_at_undefined = {
        { "1.1.1", NULL, NULL, 1, NULL,
                NULL, NULL, NULL, NULL,
-               0, 0, 0, 1, 3 }, /* LDAPAttributeType */
+               0, 0, 0, 1, 3, NULL }, /* LDAPAttributeType */
        { sizeof("UNDEFINED")-1, "UNDEFINED" }, /* cname */
        NULL, /* sup */
        NULL, /* subtypes */
@@ -735,7 +784,7 @@ static AttributeType slap_at_undefined = {
        NULL, /* syntax (this may need to be defined) */
        (AttributeTypeSchemaCheckFN *) 0, /* schema check function */
        SLAP_AT_ABSTRACT|SLAP_AT_FINAL, /* mask */
-       NULL, /* next */
+       { NULL }, /* next */
        NULL /* attribute description */
        /* mutex (don't know how to initialize it :) */
 };
@@ -1190,3 +1239,29 @@ static int administrativeRoleAttribute (
                attr->a_desc->ad_cname.bv_val );
        return LDAP_OBJECT_CLASS_VIOLATION;
 }
+
+static int dynamicAttribute (
+       Backend *be,
+       Entry *e,
+       Attribute *attr,
+       const char** text,
+       char *textbuf, size_t textlen )
+{
+       *text = textbuf;
+
+       if( !SLAP_DYNAMIC(be) ) {
+               snprintf( textbuf, textlen,
+                       "attribute \"%s\" not supported in context",
+                       attr->a_desc->ad_cname.bv_val );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       if( !is_entry_dynamicObject( e ) ) {
+               snprintf( textbuf, textlen,
+                       "attribute \"%s\" only allowed in dynamic object",
+                       attr->a_desc->ad_cname.bv_val );
+               return LDAP_OBJECT_CLASS_VIOLATION;
+       }
+
+       return LDAP_SUCCESS;
+}
index 4699633403c4bc08a846577bab2b3e535aaefb2a..ebab4bd087eae55b48a4574ccbef7650185fa625 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
 #include <ac/socket.h>
 
 #include "ldap_pvt.h"
+#include "lutil.h"
 #include "slap.h"
 
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+static char **anlist2charray( AttributeName *an );
+static Slapi_PBlock *initSearchPlugin( Backend *be, Connection *conn, Operation *op,
+       struct berval *base, int scope, int deref, int sizelimit, int timelimit,
+       Filter *filter, struct berval *fstr, char **attrs,
+       int attrsonly, int managedsait );
+static int doPreSearchPluginFNs( Backend *be, Slapi_PBlock *pb );
+static int doSearchRewriteFNs( Backend *be, Slapi_PBlock *pb, Filter **filter, struct berval *fstr );
+static void doPostSearchPluginFNs( Backend *be, Slapi_PBlock *pb );
+#endif /* LDAPI_SLAPI */
+
 int
 do_search(
     Connection *conn,  /* where to send results */
@@ -43,6 +56,10 @@ do_search(
        int                     rc;
        const char      *text;
        int                     manageDSAit;
+#ifdef LDAP_SLAPI
+       Slapi_PBlock    *pb = NULL;
+       char            **attrs = NULL;
+#endif
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_search: conn %d\n", conn->c_connid, 0, 0 );
@@ -209,9 +226,38 @@ do_search(
        Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );
 #endif
 
-       Statslog( LDAP_DEBUG_STATS,
-           "conn=%lu op=%lu SRCH base=\"%s\" scope=%d filter=\"%s\"\n",
-           op->o_connid, op->o_opid, pbase.bv_val, scope, fstr.bv_val );
+       if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
+               char abuf[BUFSIZ/2], *ptr = abuf;
+               int len = 0, alen;
+
+               Statslog( LDAP_DEBUG_STATS,
+                       "conn=%lu op=%lu SRCH base=\"%s\" scope=%d filter=\"%s\"\n",
+                       op->o_connid, op->o_opid, pbase.bv_val, scope, fstr.bv_val );
+
+               for ( i = 0; i<siz; i++ ) {
+                       alen = an[i].an_name.bv_len;
+                       if (alen >= sizeof(abuf)) {
+                               alen = sizeof(abuf)-1;
+                       }
+                       if (len && (len + 1 + alen >= sizeof(abuf))) {
+                               Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu SRCH attr=%s\n",
+                                   op->o_connid, op->o_opid, abuf, 0, 0 );
+                               len = 0;
+                               ptr = abuf;
+                       }
+                       if (len) {
+                               *ptr++ = ' ';
+                               len++;
+                       }
+                       ptr = lutil_strncopy(ptr, an[i].an_name.bv_val, alen);
+                       len += alen;
+                       *ptr = '\0';
+               }
+               if (len) {
+                       Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu SRCH attr=%s\n",
+                               op->o_connid, op->o_opid, abuf, 0, 0 );
+               }
+       }
 
        manageDSAit = get_manageDSAit( op );
 
@@ -221,7 +267,7 @@ do_search(
                if ( nbase.bv_len == 0 ) {
 #ifdef LDAP_CONNECTIONLESS
                        /* Ignore LDAPv2 CLDAP Root DSE queries */
-                       if (op->o_protocol==LDAP_VERSION2 && conn->c_is_udp) {
+                       if (op->o_protocol == LDAP_VERSION2 && conn->c_is_udp) {
                                goto return_results;
                        }
 #endif
@@ -233,7 +279,19 @@ do_search(
                                goto return_results;
                        }
 
+#ifdef LDAP_SLAPI
+                       attrs = anlist2charray( an );
+                       pb = initSearchPlugin( NULL, conn, op, &nbase, scope,
+                               deref, sizelimit, timelimit, filter, &fstr,
+                               attrs, attrsonly, manageDSAit );
+                       rc = doPreSearchPluginFNs( NULL, pb );
+                       if ( rc == LDAP_SUCCESS ) {
+                               doSearchRewriteFNs( NULL, pb, &filter, &fstr );
+#endif /* LDAP_SLAPI */
                        rc = root_dse_info( conn, &entry, &text );
+#ifdef LDAP_SLAPI
+                       }
+#endif /* LDAP_SLAPI */
 
                } else if ( bvmatch( &nbase, &global_schemandn ) ) {
                        /* check restrictions */
@@ -244,12 +302,27 @@ do_search(
                                goto return_results;
                        }
 
+#ifdef LDAP_SLAPI
+                       attrs = anlist2charray( an );
+                       pb = initSearchPlugin( NULL, conn, op, &nbase, scope,
+                               deref, sizelimit, timelimit, filter, &fstr,
+                               attrs, attrsonly, manageDSAit );
+                       rc = doPreSearchPluginFNs( NULL, pb );
+                       if ( rc == LDAP_SUCCESS ) {
+                               doSearchRewriteFNs( NULL, pb, &filter, &fstr );
+#endif /* LDAP_SLAPI */
                        rc = schema_info( &entry, &text );
+#ifdef LDAP_SLAPI
+                       }
+#endif /* LDAP_SLAPI */
                }
 
                if( rc != LDAP_SUCCESS ) {
                        send_ldap_result( conn, op, rc,
                                NULL, text, NULL, NULL );
+#ifdef LDAP_SLAPI
+                       doPostSearchPluginFNs( NULL, pb );
+#endif /* LDAP_SLAPI */
                        goto return_results;
 
                } else if ( entry != NULL ) {
@@ -264,7 +337,9 @@ do_search(
 
                        send_ldap_result( conn, op, LDAP_SUCCESS,
                                NULL, NULL, NULL, NULL );
-
+#ifdef LDAP_SLAPI
+                       doPostSearchPluginFNs( NULL, pb );
+#endif /* LDAP_SLAPI */
                        goto return_results;
                }
        }
@@ -310,6 +385,20 @@ do_search(
        /* deref the base if needed */
        suffix_alias( be, &nbase );
 
+#ifdef LDAP_SLAPI
+       attrs = anlist2charray( an );
+       pb = initSearchPlugin( be, conn, op, &pbase,
+               scope, deref, sizelimit,
+               timelimit, filter, &fstr, attrs, attrsonly,
+               manageDSAit );
+       rc = doPreSearchPluginFNs( be, pb );
+       if ( rc != LDAP_SUCCESS ) {
+               goto return_results;
+       }
+
+       doSearchRewriteFNs( be, pb, &filter, &fstr );
+#endif /* LDAP_SLAPI */
+
        /* actually do the search and send the result(s) */
        if ( be->be_search ) {
                (*be->be_search)( be, conn, op, &pbase, &nbase,
@@ -321,18 +410,155 @@ do_search(
                        NULL, NULL );
        }
 
+#ifdef LDAP_SLAPI
+       doPostSearchPluginFNs( be, pb );
+#endif /* LDAP_SLAPI */
+
 return_results:;
+
 #ifdef LDAP_CLIENT_UPDATE
-       if ( !( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
-#endif /* LDAP_CLIENT_UPDATE */
-       {
-               if( pbase.bv_val != NULL) free( pbase.bv_val );
-               if( nbase.bv_val != NULL) free( nbase.bv_val );
+       if ( ( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
+               return rc;
+#endif
+#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
+       else
+#endif
+#ifdef LDAP_SYNC
+       if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) )
+               return rc;
+#endif
+
+       if( pbase.bv_val != NULL) free( pbase.bv_val );
+       if( nbase.bv_val != NULL) free( nbase.bv_val );
+
+       if( fstr.bv_val != NULL) free( fstr.bv_val );
+       if( filter != NULL) filter_free( filter );
+       if( an != NULL ) free( an );
+#ifdef LDAP_SLAPI
+       if( attrs != NULL) ch_free( attrs );
+#endif /* LDAP_SLAPI */
+
+       return rc;
+}
+
+#ifdef LDAP_SLAPI
+
+static char **anlist2charray( AttributeName *an )
+{
+       char **attrs;
+       int i;
 
-               if( fstr.bv_val != NULL) free( fstr.bv_val );
-               if( filter != NULL) filter_free( filter );
-               if( an != NULL ) free( an );
+       if ( an != NULL ) {
+               for ( i = 0; an[i].an_name.bv_val != NULL; i++ )
+                       ;
+               attrs = (char **)ch_malloc( (i + 1) * sizeof(char *) );
+               for ( i = 0; an[i].an_name.bv_val != NULL; i++ ) {
+                       attrs[i] = an[i].an_name.bv_val;
+               }
+               attrs[i] = NULL;
+       } else {
+               attrs = NULL;
+       }
+
+       return attrs;
+}
+
+static Slapi_PBlock *initSearchPlugin( Backend *be, Connection *conn, Operation *op,
+       struct berval *base, int scope, int deref, int sizelimit,
+       int timelimit, Filter *filter, struct berval *fstr,
+       char **attrs, int attrsonly, int managedsait )
+{
+       Slapi_PBlock *pb;
+
+       pb = op->o_pb;
+
+       slapi_x_backend_set_pb( pb, be );
+       slapi_x_connection_set_pb( pb, conn );
+       slapi_x_operation_set_pb( pb, op );
+       slapi_pblock_set( pb, SLAPI_SEARCH_TARGET, (void *)base->bv_val );
+       slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, (void *)scope );
+       slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, (void *)deref );
+       slapi_pblock_set( pb, SLAPI_SEARCH_SIZELIMIT, (void *)sizelimit );
+       slapi_pblock_set( pb, SLAPI_SEARCH_TIMELIMIT, (void *)timelimit );
+       slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, (void *)filter );
+       slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, (void *)fstr->bv_val );
+       slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS, (void *)attrs );
+       slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, (void *)attrsonly );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)managedsait );
+
+       return pb;
+}
+
+static int doPreSearchPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+       int rc;
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_SEARCH_FN, pb );
+       if ( rc != 0 ) {
+               /*
+                * A preoperation plugin failure will abort the
+                * entire operation.
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "doPreSearchPluginFNs: search preoperation plugin "
+                               "returned %d\n", rc, 0, 0 );
+#else
+               Debug(LDAP_DEBUG_TRACE, "doPreSearchPluginFNs: search preoperation plugin "
+                               "returned %d.\n", rc, 0, 0);
+#endif
+               if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0)
+                       rc = LDAP_OTHER;
+       } else {
+               rc = LDAP_SUCCESS;
        }
 
        return rc;
 }
+
+static int doSearchRewriteFNs( Backend *be, Slapi_PBlock *pb, Filter **filter, struct berval *fstr )
+{
+       if ( doPluginFNs( be, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb ) == 0 ) {
+               /*
+                * The plugin can set the SLAPI_SEARCH_FILTER.
+                * SLAPI_SEARCH_STRFILER is not normative.
+                */
+               slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, (void *)filter);
+               ch_free( fstr->bv_val );
+               filter2bv( *filter, fstr );
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, ARGS, 
+                       "doSearchRewriteFNs: after compute_rewrite_search filter: %s\n", 
+                       fstr->bv_len ? fstr->bv_val : "empty", 0, 0 );
+#else
+               Debug( LDAP_DEBUG_ARGS, "    after compute_rewrite_search filter: %s\n",
+                       fstr->bv_len ? fstr->bv_val : "empty", 0, 0 );
+#endif
+       }
+
+       return LDAP_SUCCESS;
+}
+
+static void doPostSearchPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+       if ( doPluginFNs( be, SLAPI_PLUGIN_POST_SEARCH_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "doPostSearchPluginFNs: search postoperation plugins "
+                               "failed\n", 0, 0, 0 );
+#else
+               Debug(LDAP_DEBUG_TRACE, "doPostSearchPluginFNs: search postoperation plugins "
+                               "failed.\n", 0, 0, 0);
+#endif
+       }
+}
+
+void dummy(void)
+{
+       /*
+        * XXX slapi_search_internal() was no getting pulled
+        * in; all manner of linker flags failed to link it.
+        * FIXME
+        */
+       slapi_search_internal( NULL, 0, NULL, NULL, NULL, 0 );
+}
+#endif /* LDAP_SLAPI */
+
diff --git a/servers/slapd/sets.h b/servers/slapd/sets.h
new file mode 100644 (file)
index 0000000..6e3032b
--- /dev/null
@@ -0,0 +1,32 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#ifndef SLAP_SETS_H_
+#define SLAP_SETS_H_
+
+#include <ldap_cdefs.h>
+
+LDAP_BEGIN_DECL
+
+/* this routine needs to return the bervals instead of
+ * plain strings, since syntax is not known.  It should
+ * also return the syntax or some "comparison cookie"
+ * that is used by set_filter.
+ */
+typedef BerVarray (SLAP_SET_GATHER)(
+       void *cookie, struct berval *name, struct berval *attr);
+
+LDAP_SLAPD_F (long) slap_set_size(BerVarray set);
+LDAP_SLAPD_F (void) slap_set_dispose(BerVarray set);
+
+LDAP_SLAPD_F (int) slap_set_filter(
+       SLAP_SET_GATHER gatherer,
+       void *cookie, struct berval *filter,
+       struct berval *user, struct berval *this, BerVarray *results);
+
+LDAP_END_DECL
+
+#endif
index df8ce9accf3752f403feac5ca9f3f39158e2e1ba..b0801608cce641de653c330111dfbd557b55eb7e 100644 (file)
@@ -1,7 +1,7 @@
 /* slap.h - stand alone ldap server include file */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -64,11 +64,9 @@ LDAP_BEGIN_DECL
 #define SLAPD_ANONYMOUS "cn=anonymous"
 
 /* LDAPMod.mod_op value ===> Must be kept in sync with ldap.h!
- *
  * This is a value used internally by the backends. It is needed to allow
  * adding values that already exist without getting an error as required by
  * modrdn when the new rdn was already an attribute value itself.
- * JCG 05/1999 (gomez@engr.sgi.com)
  */
 #define SLAP_MOD_SOFTADD       0x1000
 
@@ -143,8 +141,6 @@ LDAP_BEGIN_DECL
 #define SLAPD_ACI_SYNTAX               "1.3.6.1.4.1.4203.666.2.1"
 #endif
 
-#define SLAPD_OCTETSTRING_SYNTAX "1.3.6.1.4.1.1466.115.121.1.40"
-
 /* change this to "OpenLDAPset" */
 #define SLAPD_ACI_SET_ATTR             "template"
 
@@ -169,6 +165,10 @@ typedef struct slap_ssf_set {
        slap_ssf_t sss_simple_bind;
 } slap_ssf_set_t;
 
+/* Flags for telling slap_sasl_getdn() what type of identity is being passed */
+#define SLAP_GETDN_AUTHCID 2
+#define SLAP_GETDN_AUTHZID 4
+
 /*
  * Index types
  */
@@ -201,7 +201,7 @@ typedef struct slap_ssf_set {
 
 #define SLAP_INDEX_FLAGS         0xF000UL
 #define SLAP_INDEX_NOSUBTYPES    0x1000UL /* don't use index w/ subtypes */
-#define SLAP_INDEX_NOLANG        0x2000UL /* don't use index w/ lang */
+#define SLAP_INDEX_NOTAGS        0x2000UL /* don't use index w/ tags */
 
 /*
  * there is a single index for each attribute.  these prefixes ensure
@@ -272,7 +272,7 @@ extern int slap_inet4or6;
 typedef struct slap_oid_macro {
        struct berval som_oid;
        char **som_names;
-       struct slap_oid_macro *som_next;
+       LDAP_SLIST_ENTRY(slap_oid_macro) som_next;
 } OidMacro;
 
 /* forward declarations */
@@ -322,7 +322,7 @@ typedef struct slap_syntax {
        slap_syntax_transform_func      *ssyn_str2ber;
 #endif
 
-       struct slap_syntax              *ssyn_next;
+       LDAP_SLIST_ENTRY(slap_syntax) ssyn_next;
 } Syntax;
 
 #define slap_syntax_is_flag(s,flag) ((int)((s)->ssyn_flags & (flag)) ? 1 : 0)
@@ -394,7 +394,7 @@ typedef struct slap_matching_rule {
        struct berval                   smr_str;
        /*
         * Note: the former
-       ber_len_t       smr_oidlen;
+        *                      ber_len_t       smr_oidlen;
         * has been replaced by a struct berval that uses the value
         * provided by smr_mrule.mr_oid; a macro that expands to
         * the bv_len field of the berval is provided for backward
@@ -434,7 +434,7 @@ typedef struct slap_matching_rule {
 #define SLAP_MR_ASSERTION_SYNTAX_MATCH                 0x0000U
 #define SLAP_MR_VALUE_SYNTAX_MATCH                             0x0001U
 #define SLAP_MR_VALUE_SYNTAX_CONVERTED_MATCH   0x0003U
-#define SLAP_MR_VALUE_NORMALIZED_MATCH                 0x0004U
+#define SLAP_MR_VALUE_NORMALIZED_MATCH 0x0004U
 
 #define SLAP_IS_MR_ASSERTION_SYNTAX_MATCH( usage ) \
        (!((usage) & SLAP_MR_VALUE_SYNTAX_MATCH))
@@ -456,14 +456,14 @@ typedef struct slap_matching_rule {
        slap_mr_filter_func             *smr_filter;
 
        /*
-        * null terminated list of syntaxes compatible with this syntax
+        * null terminated array of syntaxes compatible with this syntax
         * note: when MS_EXT is set, this MUST NOT contain the assertion
         * syntax of the rule.  When MS_EXT is not set, it MAY.
         */
        Syntax                                  **smr_compat_syntaxes;
 
        struct slap_matching_rule       *smr_associated;
-       struct slap_matching_rule       *smr_next;
+       LDAP_SLIST_ENTRY(slap_matching_rule)smr_next;
 
 #define smr_oid                                smr_mrule.mr_oid
 #define smr_names                      smr_mrule.mr_names
@@ -479,7 +479,7 @@ struct slap_matching_rule_use {
        /* RFC2252 string representation */
        struct berval                   smru_str;
 
-       struct slap_matching_rule_use   *smru_next;
+       LDAP_SLIST_ENTRY(slap_matching_rule_use) smru_next;
 
 #define smru_oid                       smru_mruleuse.mru_oid
 #define smru_names                     smru_mruleuse.mru_names
@@ -533,7 +533,7 @@ typedef struct slap_attribute_type {
 #define SLAP_AT_HIDE           0x8000U /* hide attribute */
        slap_mask_t                                     sat_flags;
 
-       struct slap_attribute_type      *sat_next;
+       LDAP_SLIST_ENTRY(slap_attribute_type) sat_next;
 
 #define sat_oid                                sat_atype.at_oid
 #define sat_names                      sat_atype.at_names
@@ -587,7 +587,7 @@ typedef struct slap_object_class {
 #define soc_at_oids_may                soc_oclass.oc_at_oids_may
 #define soc_extensions         soc_oclass.oc_extensions
 
-       struct slap_object_class        *soc_next;
+       LDAP_SLIST_ENTRY(slap_object_class) soc_next;
 } ObjectClass;
 
 #define        SLAP_OC_ALIAS           0x0001
@@ -619,21 +619,19 @@ typedef struct slap_content_rule {
 #define scr_at_oids_may                scr_crule.cr_at_oids_may
 #define scr_at_oids_not                scr_crule.cr_at_oids_not
 
-       struct slap_content_rule *scr_next;
+       LDAP_SLIST_ENTRY( slap_content_rule ) scr_next;
 } ContentRule;
 
-/*
- * represents a recognized attribute description ( type + options )
- */
+/* Represents a recognized attribute description ( type + options ). */
 typedef struct slap_attr_desc {
        struct slap_attr_desc *ad_next;
        AttributeType *ad_type;         /* attribute type, must be specified */
        struct berval ad_cname;         /* canonical name, must be specified */
-       struct berval ad_lang;          /* empty if no language tags */
+       struct berval ad_tags;          /* empty if no tagging options */
        unsigned ad_flags;
 #define SLAP_DESC_NONE                 0x00U
 #define SLAP_DESC_BINARY               0x01U
-#define SLAP_DESC_LANG_RANGE   0x80U
+#define SLAP_DESC_TAG_RANGE            0x80U
 } AttributeDescription;
 
 typedef struct slap_attr_name {
@@ -642,9 +640,9 @@ typedef struct slap_attr_name {
        ObjectClass *an_oc;
 } AttributeName;
 
-#define slap_ad_is_lang(ad)                    ( (ad)->ad_lang.bv_len != 0 )
-#define slap_ad_is_lang_range(ad)      \
-       ( ((ad)->ad_flags & SLAP_DESC_LANG_RANGE) ? 1 : 0 )
+#define slap_ad_is_tagged(ad)                  ( (ad)->ad_tags.bv_len != 0 )
+#define slap_ad_is_tag_range(ad)       \
+       ( ((ad)->ad_flags & SLAP_DESC_TAG_RANGE) ? 1 : 0 )
 #define slap_ad_is_binary(ad)          \
        ( ((ad)->ad_flags & SLAP_DESC_BINARY) ? 1 : 0 )
 
@@ -661,6 +659,8 @@ struct slap_internal_schema {
        ObjectClass *si_oc_subentry;
        ObjectClass *si_oc_subschema;
        ObjectClass *si_oc_monitor;
+       ObjectClass *si_oc_collectiveAttributeSubentry;
+       ObjectClass *si_oc_dynamicObject;
 
        /* objectClass attribute descriptions */
        AttributeDescription *si_ad_objectClass;
@@ -673,6 +673,8 @@ struct slap_internal_schema {
        AttributeDescription *si_ad_modifyTimestamp;
        AttributeDescription *si_ad_hasSubordinates;
        AttributeDescription *si_ad_subschemaSubentry;
+       AttributeDescription *si_ad_collectiveSubentries;
+       AttributeDescription *si_ad_collectiveExclusions;
        AttributeDescription *si_ad_entryUUID;
        AttributeDescription *si_ad_entryCSN;
        AttributeDescription *si_ad_superiorUUID;
@@ -716,6 +718,10 @@ struct slap_internal_schema {
        AttributeDescription *si_ad_aci;
 #endif
 
+       /* dynamic entries */
+       AttributeDescription *si_ad_entryTtl;
+       AttributeDescription *si_ad_dynamicSubtrees;
+
        /* Other attributes descriptions */
        AttributeDescription *si_ad_distinguishedName;
        AttributeDescription *si_ad_name;
@@ -823,29 +829,50 @@ typedef struct slap_filter {
 #define SLAPD_COMPARE_UNDEFINED        ((ber_int_t) -1)
 
 typedef struct slap_valuesreturnfilter {
-       ber_tag_t       f_choice;
+       ber_tag_t       vrf_choice;
 
        union vrf_un_u {
                /* precomputed result */
-               ber_int_t f_un_result;
+               ber_int_t vrf_un_result;
 
                /* DN */
-               char *f_un_dn;
+               char *vrf_un_dn;
 
                /* present */
-               AttributeDescription *f_un_desc;
+               AttributeDescription *vrf_un_desc;
 
                /* simple value assertion */
-               AttributeAssertion *f_un_ava;
+               AttributeAssertion *vrf_un_ava;
 
                /* substring assertion */
-               SubstringsAssertion *f_un_ssa;
+               SubstringsAssertion *vrf_un_ssa;
 
                /* matching rule assertion */
-               MatchingRuleAssertion *f_un_mra;
-       } f_un;
-
-       struct slap_valuesreturnfilter  *f_next;
+               MatchingRuleAssertion *vrf_un_mra;
+
+#define vrf_result             vrf_un.vrf_un_result
+#define vrf_dn                 vrf_un.vrf_un_dn
+#define vrf_desc               vrf_un.vrf_un_desc
+#define vrf_ava                        vrf_un.vrf_un_ava
+#define vrf_av_desc            vrf_un.vrf_un_ava->aa_desc
+#define vrf_av_value   vrf_un.vrf_un_ava->aa_value
+#define vrf_ssa                        vrf_un.vrf_un_ssa
+#define vrf_sub                        vrf_un.vrf_un_ssa
+#define vrf_sub_desc   vrf_un.vrf_un_ssa->sa_desc
+#define vrf_sub_initial        vrf_un.vrf_un_ssa->sa_initial
+#define vrf_sub_any            vrf_un.vrf_un_ssa->sa_any
+#define vrf_sub_final  vrf_un.vrf_un_ssa->sa_final
+#define vrf_mra                        vrf_un.vrf_un_mra
+#define vrf_mr_rule            vrf_un.vrf_un_mra->ma_rule
+#define vrf_mr_rule_text       vrf_un.vrf_un_mra->ma_rule_text
+#define vrf_mr_desc            vrf_un.vrf_un_mra->ma_desc
+#define vrf_mr_value           vrf_un.vrf_un_mra->ma_value
+#define        vrf_mr_dnattrs  vrf_un.vrf_un_mra->ma_dnattrs
+
+
+       } vrf_un;
+
+       struct slap_valuesreturnfilter  *vrf_next;
 } ValuesReturnFilter;
 
 /*
@@ -1090,6 +1117,7 @@ typedef struct slap_acl_state {
 
        /* Access state */
        AccessControl *as_vd_acl;
+       AccessControl *as_vi_acl;
        slap_mask_t as_vd_acl_mask;
        regmatch_t as_vd_acl_matches[MAXREMATCHES];
        int as_vd_acl_count;
@@ -1098,8 +1126,10 @@ typedef struct slap_acl_state {
        int as_vd_access_count;
 
        int as_result;
+       AttributeDescription *as_vd_ad;
 } AccessControlState;
-#define ACL_STATE_INIT { ACL_STATE_NOT_RECORDED, NULL, 0UL, { { 0, 0 } }, 0, NULL, 0, 0 }
+#define ACL_STATE_INIT { ACL_STATE_NOT_RECORDED, NULL, NULL, 0UL, \
+       { { 0, 0 } }, 0, NULL, 0, 0, NULL }
 
 /*
  * replog moddn param structure
@@ -1147,6 +1177,8 @@ struct slap_limits_set {
        int     lms_s_soft;
        int     lms_s_hard;
        int     lms_s_unchecked;
+       int     lms_s_pr;
+       int     lms_s_pr_hide;
 };
 
 struct slap_limits {
@@ -1206,9 +1238,7 @@ struct slap_backend_db {
  * (in previous use there was a flaw with back-bdb and back-ldbm; now it 
  * is fixed).
  */
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
 #define                be_has_subordinates bd_info->bi_has_subordinates
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
 #define                be_controls     bd_info->bi_controls
 
@@ -1311,6 +1341,8 @@ struct slap_backend_db {
        BerVarray       be_update_refs; /* where to refer modifying clients to */
        char    *be_realm;
        void    *be_private;    /* anything the backend database needs     */
+
+       void    *be_pb;         /* Netscape plugin */
 };
 
 struct slap_conn;
@@ -1409,11 +1441,9 @@ typedef int (BI_operational)  LDAP_P((Backend *bd,
                struct slap_conn *c, struct slap_op *o,
                Entry *e, AttributeName *attrs, int opattrs, Attribute **a ));
 
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
 typedef int (BI_has_subordinates) LDAP_P((Backend *bd,
                struct slap_conn *c, struct slap_op *o,
                Entry *e, int *has_subordinates ));
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
 typedef int (BI_connection_init) LDAP_P((BackendDB *bd,
                struct slap_conn *c));
@@ -1508,9 +1538,7 @@ struct slap_backend_info {
        BI_acl_attribute        *bi_acl_attribute;
 
        BI_operational  *bi_operational;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
        BI_has_subordinates     *bi_has_subordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
        BI_connection_init      *bi_connection_init;
        BI_connection_destroy   *bi_connection_destroy;
@@ -1564,10 +1592,14 @@ typedef void (slap_sresult)( struct slap_conn *, struct slap_op *,
 typedef int (slap_sendentry)( BackendDB *, struct slap_conn *,
        struct slap_op *, Entry *, AttributeName *, int, LDAPControl **);
 
+typedef int (slap_sendreference)( BackendDB *, struct slap_conn *,
+       struct slap_op *, Entry *, BerVarray, LDAPControl **, BerVarray * );
+
 typedef struct slap_callback {
        slap_response *sc_response;
        slap_sresult *sc_sresult;
        slap_sendentry *sc_sendentry;
+       slap_sendreference *sc_sendreference;
        void *sc_private;
 } slap_callback;
 
@@ -1582,14 +1614,14 @@ typedef struct slap_paged_state {
 } PagedResultsState;
 
 
-#ifdef LDAP_CLIENT_UPDATE
-#define LCUP_PSEARCH_BY_ADD 0x01
-#define LCUP_PSEARCH_BY_DELETE 0x02
-#define LCUP_PSEARCH_BY_PREMODIFY 0x03
-#define LCUP_PSEARCH_BY_MODIFY 0x04
-#define LCUP_PSEARCH_BY_SCOPEOUT 0x05
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+#define LDAP_PSEARCH_BY_ADD            0x01
+#define LDAP_PSEARCH_BY_DELETE         0x02
+#define LDAP_PSEARCH_BY_PREMODIFY      0x03
+#define LDAP_PSEARCH_BY_MODIFY         0x04
+#define LDAP_PSEARCH_BY_SCOPEOUT       0x05
 
-struct lcup_search_spec {
+struct ldap_psearch_spec {
        struct slap_op  *op;
        struct berval   *base;
        struct berval   *nbase;
@@ -1601,17 +1633,16 @@ struct lcup_search_spec {
        struct berval   *filterstr;
        AttributeName   *attrs;
        int             attrsonly;
-       struct lcup_entry *elist;
-       ldap_pvt_thread_mutex_t elist_mutex;
+       int             protocol;
        int             entry_count;
-       LDAP_LIST_ENTRY(lcup_search_spec) link;
+       LDAP_LIST_ENTRY(ldap_psearch_spec) link;
 };
 
 struct psid_entry {
-       struct lcup_search_spec* ps;
+       struct ldap_psearch_spec* ps;
        LDAP_LIST_ENTRY(psid_entry) link;
 };
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
 
 
 /*
@@ -1627,9 +1658,12 @@ typedef struct slap_op {
        ber_tag_t       o_tag;          /* tag of the request */
        time_t          o_time;         /* time op was initiated */
 
+       char *          o_extendedop;   /* extended operation OID */
+
        ldap_pvt_thread_t       o_tid;  /* thread handling this op */
 
        volatile sig_atomic_t o_abandon;        /* abandon flag */
+       volatile sig_atomic_t o_cancel;         /* cancel flag */
 
        char o_do_not_cache;    /* don't cache from this op */
 
@@ -1637,14 +1671,37 @@ typedef struct slap_op {
 #define SLAP_NONCRITICAL_CONTROL 1
 #define SLAP_CRITICAL_CONTROL 2
        char o_managedsait;
+#define get_manageDSAit(op)                            ((int)(op)->o_managedsait)
+
        char o_noop;
+       char o_proxy_authz;
+
        char o_subentries;
+#define get_subentries(op)                             ((int)(op)->o_subentries)
        char o_subentries_visibility;
+#define get_subentries_visibility(op)  ((int)(op)->o_subentries_visibility)
+
        char o_valuesreturnfilter;
 
+#ifdef LDAP_CONTROL_PERMITMODIFY
+       char o_permitmodify;
+#define get_permitmodify(op)                   ((int)(op)->o_permitmodify)
+#else
+#define get_permitmodify(op)                   (0)
+#endif
+
+#ifdef LDAP_CONTROL_NOREFERRALS
+       char o_noreferrals;
+#endif
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
        char o_pagedresults;
+#define get_pagedresults(op)                   ((int)(op)->o_pagedresults)
        ber_int_t o_pagedresults_size;
        PagedResultsState o_pagedresults_state;
+#else
+#define get_pagedresults(op)                   (0)
+#endif
 
 #ifdef LDAP_CLIENT_UPDATE
        char o_clientupdate;
@@ -1652,13 +1709,26 @@ typedef struct slap_op {
 #define SLAP_LCUP_NONE                         (0x0)
 #define SLAP_LCUP_SYNC                                 (0x1)
 #define SLAP_LCUP_PERSIST                      (0x2)
-#define SLAP_LCUP_SYNC_AND_PERSIST     (0x3)
+#define SLAP_LCUP_SYNC_AND_PERSIST             (0x3)
        ber_int_t o_clientupdate_interval;
        struct berval o_clientupdate_state;
-       LDAP_LIST_HEAD(lss, lcup_search_spec) psearch_spec;
+#endif
+
+#ifdef LDAP_SYNC
+       char o_sync;
+       char o_sync_mode;
+#define SLAP_SYNC_NONE                         (0x0)
+#define SLAP_SYNC_REFRESH                      (0x1)
+#define SLAP_SYNC_PERSIST                      (0x2)
+#define SLAP_SYNC_REFRESH_AND_PERSIST          (0x3)
+       struct berval o_sync_state;
+#endif
+
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+       LDAP_LIST_HEAD(lss, ldap_psearch_spec) psearch_spec;
        LDAP_LIST_HEAD(pe, psid_entry) premodify_list;
        LDAP_LIST_ENTRY(slap_op) link;
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
 
 #ifdef LDAP_CONNECTIONLESS
        Sockaddr        o_peeraddr;     /* UDP peer address               */
@@ -1666,6 +1736,9 @@ typedef struct slap_op {
        AuthorizationInformation o_authz;
 
        BerElement      *o_ber;         /* ber of the request             */
+#ifdef LDAP_CONNECTIONLESS
+       BerElement      *o_res_ber;     /* ber of the reply               */
+#endif
        slap_callback   *o_callback;    /* callback pointers */
        LDAPControl     **o_ctrls;       /* controls */
 
@@ -1674,11 +1747,100 @@ typedef struct slap_op {
 
        LDAP_STAILQ_ENTRY(slap_op)      o_next; /* next operation in list         */
        ValuesReturnFilter *vrFilter; /* Structure represents ValuesReturnFilter */
+
+#ifdef LDAP_SLAPI
+       void    *o_pb;                  /* NS-SLAPI plugin */
+#endif
 } Operation;
 
-#define get_manageDSAit(op)                            ((int)(op)->o_managedsait)
-#define get_subentries(op)                             ((int)(op)->o_subentries)
-#define get_subentries_visibility(op)  ((int)(op)->o_subentries_visibility)
+typedef void (*SEND_LDAP_RESULT)(
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               ber_int_t err,
+                               const char *matched,
+                               const char *text,
+                               BerVarray ref,
+                               LDAPControl **ctrls
+                               );
+
+#define send_ldap_result( conn, op, err, matched, text, ref, ctrls  ) \
+(*conn->c_send_ldap_result)( conn, op, err, matched, text, ref, ctrls )
+
+
+typedef int (*SEND_SEARCH_ENTRY)(
+                               struct slap_backend_db *be,
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               struct slap_entry *e,
+                               AttributeName *attrs,
+                               int attrsonly,
+                               LDAPControl **ctrls
+                               );
+
+#define send_search_entry( be, conn, op, e, attrs, attrsonly, ctrls) \
+(*conn->c_send_search_entry)( be, conn, op, e, attrs, attrsonly, ctrls)
+
+
+typedef void (*SEND_SEARCH_RESULT)(
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               ber_int_t err,
+                               const char *matched,
+                               const char *text,
+                               BerVarray   refs,
+                               LDAPControl **ctrls,
+                               int nentries
+                               );
+
+#define send_search_result( conn, op, err, matched, text, refs, ctrls, nentries ) \
+(*conn->c_send_search_result)( conn, op, err, matched, text, refs, ctrls, nentries )
+
+
+typedef int (*SEND_SEARCH_REFERENCE)(
+                               struct slap_backend_db *be,
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               struct slap_entry *e,
+                               BerVarray refs,
+                               LDAPControl **ctrls,
+                               BerVarray *v2refs
+                               );
+
+#define send_search_reference( be, conn, op, e,  refs, ctrls, v2refs ) \
+(*conn->c_send_search_reference)( be, conn, op, e,  refs, ctrls, v2refs )
+
+
+typedef void (*SEND_LDAP_EXTENDED)(
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               ber_int_t   err,
+                               const char  *matched,
+                               const char  *text,
+                               BerVarray   refs,
+                               const char      *rspoid,
+                               struct berval *rspdata,
+                               LDAPControl **ctrls
+                               );
+
+#define send_ldap_extended( conn, op, err, matched, text, refs, rspoid, rspdata, ctrls) \
+(*conn->c_send_ldap_extended)( conn, op, err, matched, text, refs, rspoid, rspdata, ctrls )
+
+typedef void (*SEND_LDAP_INTERMEDIATE_RESP)(
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               ber_int_t   err,
+                               const char  *matched,
+                               const char  *text,
+                               BerVarray   refs,
+                               const char      *rspoid,
+                               struct berval *rspdata,
+                               LDAPControl **ctrls
+                               );
+
+#define send_ldap_intermediate_resp( conn, op, err, matched, text, refs, \
+                                    rspoid, rspdata, ctrls) \
+       (*conn->c_send_ldap_intermediate_resp)( conn, op, err, matched, text, \
+                                               refs, rspoid, rspdata, ctrls )
 
 /*
  * Caches the result of a backend_group check for ACL evaluation
@@ -1760,6 +1922,23 @@ typedef struct slap_conn {
        long    c_n_get;                /* num of get calls */
        long    c_n_read;               /* num of read calls */
        long    c_n_write;              /* num of write calls */
+
+       void    *c_pb;                  /* Netscape plugin */
+
+       /*
+        * These are the "callbacks" that are available for back-ends to
+        * supply data back to connected clients that are connected
+        * through the "front-end".
+        */
+       SEND_LDAP_RESULT c_send_ldap_result;
+       SEND_SEARCH_ENTRY c_send_search_entry;
+       SEND_SEARCH_RESULT c_send_search_result;
+       SEND_SEARCH_REFERENCE c_send_search_reference;
+       SEND_LDAP_EXTENDED c_send_ldap_extended;
+#ifdef LDAP_RES_INTERMEDIATE_RESP
+       SEND_LDAP_INTERMEDIATE_RESP c_send_ldap_intermediate_resp;
+#endif
+       
 } Connection;
 
 #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG)
@@ -1771,8 +1950,25 @@ typedef struct slap_conn {
                        syslog( ldap_syslog_level, (fmt), (connid), (opid), (arg1), \
                                (arg2), (arg3) ); \
        } while (0)
+#define StatslogTest( level ) ((ldap_debug | ldap_syslog) & (level))
+#elif defined(LDAP_DEBUG)
+#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) \
+       do { \
+               if ( ldap_debug & (level) ) \
+                       fprintf( stderr, (fmt), (connid), (opid), (arg1), (arg2), (arg3) );\
+       } while (0)
+#define StatslogTest( level ) (ldap_debug & (level))
+#elif defined(LDAP_SYSLOG)
+#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) \
+       do { \
+               if ( ldap_syslog & (level) ) \
+                       syslog( ldap_syslog_level, (fmt), (connid), (opid), (arg1), \
+                               (arg2), (arg3) ); \
+       } while (0)
+#define StatslogTest( level ) (ldap_syslog & (level))
 #else
 #define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 )
+#define StatslogTest( level ) (0)
 #endif
 
 /*
@@ -1828,6 +2024,10 @@ enum {
 #define SLAP_LCUP_ENTRY_DELETED_FALSE  0
 #endif /* LDAP_CLIENT_UPDATE */
 
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+#define SLAP_SEARCH_MAX_CTRLS   10
+#endif
+
 LDAP_END_DECL
 
 #include "proto-slap.h"
index f12dd14012b3b2e38c467f622a3124d9a15d61bc..73cf5afe3c0732e932757f7c9cebd899c5ffd286 100644 (file)
@@ -1,7 +1,7 @@
 /* syntax.c - routines to manage syntax definitions */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
@@ -22,24 +22,26 @@ struct sindexrec {
 };
 
 static Avlnode *syn_index = NULL;
-static Syntax *syn_list = NULL;
+static LDAP_SLIST_HEAD(SyntaxList, slap_syntax) syn_list
+       = LDAP_SLIST_HEAD_INITIALIZER(&syn_list);
 
 static int
 syn_index_cmp(
-    struct sindexrec   *sir1,
-    struct sindexrec   *sir2
+       const void *v_sir1,
+       const void *v_sir2
 )
 {
+       const struct sindexrec *sir1 = v_sir1, *sir2 = v_sir2;
        return (strcmp( sir1->sir_name, sir2->sir_name ));
 }
 
 static int
 syn_index_name_cmp(
-    const char         *name,
-    struct sindexrec   *sir
+       const void *name,
+       const void *sir
 )
 {
-       return (strcmp( name, sir->sir_name ));
+       return (strcmp( name, ((const struct sindexrec *)sir)->sir_name ));
 }
 
 Syntax *
@@ -47,8 +49,7 @@ syn_find( const char *synname )
 {
        struct sindexrec        *sir = NULL;
 
-       if ( (sir = (struct sindexrec *) avl_find( syn_index, synname,
-           (AVL_CMP) syn_index_name_cmp )) != NULL ) {
+       if ( (sir = avl_find( syn_index, synname, syn_index_name_cmp )) != NULL ) {
                return( sir->sir_syn );
        }
        return( NULL );
@@ -59,20 +60,23 @@ syn_find_desc( const char *syndesc, int *len )
 {
        Syntax          *synp;
 
-       for (synp = syn_list; synp; synp = synp->ssyn_next)
-               if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{')))
+       LDAP_SLIST_FOREACH(synp, &syn_list, ssyn_next) {
+               if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{' /*'}'*/ ))) {
                        return synp;
+               }
+       }
        return( NULL );
 }
 
 void
 syn_destroy( void )
 {
-       Syntax *s, *n;
+       Syntax *s;
 
        avl_free(syn_index, ldap_memfree);
-       for (s=syn_list; s; s=n) {
-               n = s->ssyn_next;
+       while( !LDAP_SLIST_EMPTY(&syn_list) ) {
+               s = LDAP_SLIST_FIRST(&syn_list);
+               LDAP_SLIST_REMOVE_HEAD(&syn_list, ssyn_next);
                ldap_syntax_free((LDAPSyntax *)s);
        }
 }
@@ -83,15 +87,10 @@ syn_insert(
     const char         **err
 )
 {
-       Syntax          **synp;
        struct sindexrec        *sir;
 
-       synp = &syn_list;
-       while ( *synp != NULL ) {
-               synp = &(*synp)->ssyn_next;
-       }
-       *synp = ssyn;
-
+       LDAP_SLIST_INSERT_HEAD( &syn_list, ssyn, ssyn_next );
        if ( ssyn->ssyn_oid ) {
                sir = (struct sindexrec *)
                        SLAP_CALLOC( 1, sizeof(struct sindexrec) );
@@ -107,8 +106,7 @@ syn_insert(
                sir->sir_name = ssyn->ssyn_oid;
                sir->sir_syn = ssyn;
                if ( avl_insert( &syn_index, (caddr_t) sir,
-                                (AVL_CMP) syn_index_cmp,
-                                (AVL_DUP) avl_dup_error ) ) {
+                                syn_index_cmp, avl_dup_error ) ) {
                        *err = ssyn->ssyn_oid;
                        ldap_memfree(sir);
                        return SLAP_SCHERR_SYN_DUP;
@@ -142,7 +140,7 @@ syn_add(
 
        AC_MEMCPY( &ssyn->ssyn_syn, syn, sizeof(LDAPSyntax) );
 
-       ssyn->ssyn_next = NULL;
+       LDAP_SLIST_NEXT(ssyn,ssyn_next) = NULL;
 
        /*
         * note: ssyn_bvoid uses the same memory of ssyn_syn.syn_oid;
@@ -216,7 +214,7 @@ syn_schema_info( Entry *e )
 
        vals[1].bv_val = NULL;
 
-       for ( syn = syn_list; syn; syn = syn->ssyn_next ) {
+       LDAP_SLIST_FOREACH(syn, &syn_list, ssyn_next ) {
                if ( ! syn->ssyn_validate ) {
                        /* skip syntaxes without validators */
                        continue;
index 73780f68d6acc17fc4f617ce540277b14267ed90..647941dfc232f010a414a975be0de020a621df0a 100644 (file)
@@ -1,5 +1,5 @@
 # $OpenLDAP$
-## Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
 ## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
 #-----------------------------------------------------------------------------
 # Portions Copyright (c) 1995 Regents of the University of Michigan.
@@ -27,7 +27,7 @@ XLIBS = $(SLAPD_L) $(LDBM_LIBS)
 XXLIBS = $(SLAPD_LIBS) \
        $(LDBM_LIBS) $(SECURITY_LIBS) \
        $(LDIF_LIBS) $(LUTIL_LIBS)
-XXXLIBS = $(MODULES_LIBS) $(LTHREAD_LIBS)
+XXXLIBS = $(LTHREAD_LIBS) $(MODULES_LIBS)
 
 STATIC_DEPENDS=@SLAPD_NO_STATIC@ ../libbackends.a
 
@@ -44,7 +44,8 @@ SLAPD_OBJS = ../config.o ../ch_malloc.o ../cr.o ../backend.o \
                ../entry.o ../dn.o ../filter.o ../str2filter.o ../ava.o \
                ../init.o ../controls.o ../kerberos.o ../passwd.o \
                ../index.o ../extended.o ../starttls.o ../sets.o ../mra.o \
-               ../referral.o ../backglue.o ../oidm.o ../mods.o
+               ../referral.o ../backglue.o ../oidm.o ../mods.o ../operation.o \
+               ../cancel.o
 
 SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o
 
index 375a6706b22f0f3d827bac6a8fe19e500b36b9c2..dd5dc46eafad0abf695c7859a43c28f109dc8eb2 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /*
@@ -42,7 +42,7 @@ send_ldap_disconnect(
 }
 
 void
-send_ldap_extended(
+slap_send_ldap_extended(
     Connection *conn,
     Operation  *op,
     ber_int_t  err,
@@ -57,6 +57,22 @@ send_ldap_extended(
        assert(0);
 }
 
+void
+slap_send_ldap_intermediate_resp(
+       Connection  *conn,
+       Operation   *op,
+       ber_int_t   err,
+       const char  *matched,
+       const char  *text,
+       BerVarray refs,
+       const char  *rspoid,
+       struct berval *rspdata,
+       LDAPControl **ctrls
+)
+{
+       assert(0);
+}
+
 void
 send_ldap_sasl(
     Connection *conn,
@@ -73,7 +89,7 @@ send_ldap_sasl(
 }
 
 void
-send_ldap_result(
+slap_send_ldap_result(
        Connection  *conn, 
        Operation   *op,
        ber_int_t     err,
@@ -87,7 +103,7 @@ send_ldap_result(
 }
 
 void
-send_search_result(
+slap_send_search_result(
        Connection  *conn, 
        Operation   *op,
        ber_int_t     err,
@@ -102,7 +118,7 @@ send_search_result(
 }
 
 int
-send_search_entry(
+slap_send_search_entry(
        Backend *be,
        Connection  *conn, 
        Operation   *op,
@@ -116,7 +132,8 @@ send_search_entry(
        return -1;
 }
 
-int send_search_reference(
+int
+slap_send_search_reference(
        Backend *be,
        Connection  *conn, 
        Operation   *op,
@@ -270,3 +287,26 @@ slap_modrdn2mods(
        return 0;
 }
 
+int
+slap_mods2entry(
+       Modifications *mods,
+       Entry **e,
+       int repl_user,
+       const char **text,
+       char *textbuf, size_t textlen )
+{
+       return 0;
+}
+
+int slap_sasl_getdn( Connection *conn, char *id, int len,
+       char *user_realm, struct berval *dn, int flags )
+{
+       return -1;
+}
+
+int slap_sasl_authorized( Connection *conn,
+       struct berval *authcDN, struct berval *authzDN )
+{
+       return -1;
+}
+
index 2004511a678686ba3d65a24c851042bde913aa5a..23fc0bf64c2c460cdfa90b69d31b7cb0108a0a39 100644 (file)
@@ -1,6 +1,6 @@
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* slapcommon.c - common routine for the slap tools */
@@ -123,6 +123,7 @@ slap_tool_init(
                case 'b':
                        base.bv_val = strdup( optarg );
                        base.bv_len = strlen( base.bv_val );
+                       break;
 
                case 'c':       /* enable continue mode */
                        continuemode++;
@@ -190,14 +191,14 @@ slap_tool_init(
                
        rc = slap_init( mode, progname );
 
-       if (rc != 0 ) {
+       if ( rc != 0 ) {
                fprintf( stderr, "%s: slap_init failed!\n", progname );
                exit( EXIT_FAILURE );
        }
 
        rc = slap_schema_init();
 
-       if (rc != 0 ) {
+       if ( rc != 0 ) {
                fprintf( stderr, "%s: slap_schema_init failed!\n", progname );
                exit( EXIT_FAILURE );
        }
@@ -216,14 +217,14 @@ slap_tool_init(
 
        rc = glue_sub_init();
 
-       if (rc != 0 ) {
+       if ( rc != 0 ) {
                fprintf( stderr, "Subordinate configuration error\n" );
                exit( EXIT_FAILURE );
        }
 
        rc = slap_schema_check();
 
-       if (rc != 0 ) {
+       if ( rc != 0 ) {
                fprintf( stderr, "%s: slap_schema_prep failed!\n", progname );
                exit( EXIT_FAILURE );
        }