]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD
authorKurt Zeilenga <kurt@openldap.org>
Mon, 23 Feb 2004 23:07:53 +0000 (23:07 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Mon, 23 Feb 2004 23:07:53 +0000 (23:07 +0000)
40 files changed:
CHANGES
build/version.var
configure
configure.in
doc/man/man5/slapd-meta.5
doc/man/man5/slapd.conf.5
doc/man/man8/slapadd.8
include/ldap_log.h
libraries/liblber/debug.c
libraries/libldap/abandon.c
libraries/libldap/cyrus.c
libraries/libldap/request.c
libraries/liblutil/passwd.c
servers/slapd/back-bdb/dbcache.c
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/search.c
servers/slapd/back-ldap/add.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/search.c
servers/slapd/back-ldbm/ldbm.c
servers/slapd/back-ldbm/search.c
servers/slapd/back-meta/search.c
servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql
servers/slapd/back-sql/search.c
servers/slapd/backglue.c
servers/slapd/connection.c
servers/slapd/delete.c
servers/slapd/filter.c
servers/slapd/limits.c
servers/slapd/main.c
servers/slapd/modrdn.c
servers/slapd/overlays/pcache.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/slap.h
servers/slapd/syncrepl.c
servers/slapd/tools/mimic.c
servers/slapd/tools/slapadd.c

diff --git a/CHANGES b/CHANGES
index 370c70ff05ca88e8124dbf35fdd6dbb1ea471904..c59a55e522c245f87436d142bb7866f9433a0c2e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,9 +1,27 @@
 OpenLDAP 2.2 Change Log
 
 OpenLDAP 2.2.6 Engineering
+       Fixed slapd SASL callback handling
+       Fixed slapd backglue sizelimit bug
+       Fixed slapd numericStringMatch bug
        Fixed numericStringsMatch mis-definition bug (ITS#2938)
+       Fixed libldap reference handling
+       Fixed libldap_r abandon msgid mutex bug 
+       Fixed liblutil NS MTA MD5 passwd len bug
+       Fixed slapd pcache DB init bug
+       Updated slapd syncrepl support
+       Updated slapd connection deferred logging
+       Updated slapd filter logging
+       Updated slapd back-ldap
+       Added slapd limit groups
        Build Environment
                Fixed test021 portable echo bug (ITS#2933, ITS#2879)
+               Fixed EBCDIC conversion bugs
+       Documentation
+               Misc. man page updates
+       Contributed Software
+               Added slapd passwd modules
+               Updated libcldap++
 
 OpenLDAP 2.2.5 Release
        Fixed slapd filter bug (ITS#2901)
index d2793e05bac0fa59e1709a59806605a68ef194f7..d1845673ef2faab7069fb0f41eeed94291315a34 100644 (file)
@@ -17,5 +17,5 @@ ol_major=2
 ol_minor=2
 ol_patch=X
 ol_api_inc=20204
-ol_api_lib=202:4:1
-ol_release_date="2004/01/22"
+ol_api_lib=202:4:2
+ol_release_date="2004/01/29"
index 47823231d49a82f2de178f2429f95d0e183ac705..c280690467ea8e11e06d7f06c64f7d7d0a5a4761 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # $OpenLDAP$
-# from OpenLDAP: pkg/ldap/configure.in,v 1.478.2.11 2004/01/01 18:16:25 kurt Exp  
+# from OpenLDAP: pkg/ldap/configure.in,v 1.478.2.12 2004/01/17 18:36:41 kurt Exp  
 
 # This work is part of OpenLDAP Software <http://www.openldap.org/>.
 #
@@ -8509,11 +8509,11 @@ else
        ol_with_sql_module=static
        if test $ol_with_dyngroup = mod ; then
                echo "configure: warning: building static dyngroup overlay" 1>&2
-               ol_with_dyngroup = yes
+               ol_with_dyngroup=yes
        fi
        if test $ol_with_proxycache = mod ; then
                echo "configure: warning: building static proxycache overlay" 1>&2
-               ol_with_proxycache = yes
+               ol_with_proxycache=yes
        fi
 fi
 
index 31915cb7dffd39c0c261859a01a838650464279b..8a73414866f527622f0bd9a668ff05c9fe92f9ed 100644 (file)
@@ -808,11 +808,11 @@ else
        ol_with_sql_module=static
        if test $ol_with_dyngroup = mod ; then
                AC_MSG_WARN([building static dyngroup overlay])
-               ol_with_dyngroup = yes
+               ol_with_dyngroup=yes
        fi
        if test $ol_with_proxycache = mod ; then
                AC_MSG_WARN([building static proxycache overlay])
-               ol_with_proxycache = yes
+               ol_with_proxycache=yes
        fi
 fi
 
index f56fe768d504217767c14cbc5b73ac94248dc83a..4f37eef4a56b6b667eac4e68f2e237acfdcbc812 100644 (file)
@@ -562,7 +562,7 @@ Determines how a string can be rewritten if a pattern is matched.
 Examples are reported below.
 .SH "Additional configuration syntax:"
 .TP
-.B rewriteMap "<map name>" "<map type>" "[ <map attrs> ]"
+.B rewriteMap "<map type>" "<map name>" "[ <map attrs> ]"
 Allows to define a map that transforms substring rewriting into
 something else.
 The map is referenced inside the substitution pattern of a rule.
index 868743b9e4d45d76cb716b4b797be3a937a51fb7..eb087bd686d80d1572a9568229e3be79b4a6ac0c 100644 (file)
@@ -292,7 +292,7 @@ can be any of
 .RS
 .RS
 .TP
-anonymous | users | [dn[.<style>]=]<pattern>
+anonymous | users | [dn[.<style>]=]<pattern> | group[/oc[/at]]=<pattern>
 
 .RE
 with
@@ -304,11 +304,11 @@ with
 The term
 .B anonymous
 matches all unauthenticated clients.
-the term
+The term
 .B users
 matches all authenticated clients;
-otherwise a
-.B regex
+otherwise an
+.B exact
 dn pattern is assumed unless otherwise specified by qualifying 
 the (optional) key string
 .B dn
@@ -337,6 +337,24 @@ The same behavior is obtained by using the
 form of the
 .B who
 clause.
+The term
+.BR group ,
+with the optional objectClass
+.B oc
+and attributeType
+.B at
+fields, followed by
+.BR pattern ,
+sets the limits for any DN listed in the values of the
+.B at
+attribute (default
+.BR member )
+of the 
+.B oc
+group objectClass (default
+.BR groupOfNames )
+whose DN exactly matches
+.BR pattern .
 
 The currently supported limits are 
 .B size
index 23cb101b93a680fc6afa51d4002a967f37a1dd65..da2825a6d6204b3b274a4345a8195fb27377a0df 100644 (file)
@@ -57,9 +57,8 @@ promote it to the syncrepl provider's content after adding
 the entries.
 .TP
 .BI \-r
-If the LDIF input represents a syncrepl provider replica,
-demote it to the syncrepl consumer replica after adding
-the entries.
+If  the  LDIF  input represents a  syncrepl  provider, demote 
+it  to  the syncrepl consumer replica after adding the entries.
 .TP
 .BI \-w
 When used with either 
index 7f1d6c7e86554c2f961c7c3a89de53184d0fce7c..d053bdf78dee143426145b5203ab35b3438fda88 100644 (file)
@@ -114,6 +114,12 @@ LDAP_BEGIN_DECL
 #   ifdef LDAP_SYSLOG
     extern int ldap_syslog;
     extern int ldap_syslog_level;
+
+#      ifdef HAVE_EBCDIC
+#      define syslog   eb_syslog
+       extern void eb_syslog(int pri, const char *fmt, ...);
+#      endif
+
 #   endif /* LDAP_SYSLOG */
 
 /* this doesn't below as part of ldap.h */
index caaa49312b3fe5631139592d27613570b4a39b61..6a4329562afbf78e721ff62a3b3ed9d682bcb651 100644 (file)
@@ -302,3 +302,23 @@ void (lutil_debug)( int debug, int level, const char *fmt, ... )
        fputs( buffer, stderr );
        va_end( vl );
 }
+
+#if defined(HAVE_EBCDIC) && defined(LDAP_SYSLOG)
+#undef syslog
+void eb_syslog( int pri, const char *fmt, ... )
+{
+       char buffer[4096];
+       va_list vl;
+
+       va_start( vl, fmt );
+       vsnprintf( buffer, sizeof(buffer), fmt, vl );
+       buffer[sizeof(buffer)-1] = '\0';
+
+       /* The syslog function appears to only work with pure EBCDIC */
+       __atoe(buffer);
+#pragma convlit(suspend)
+       syslog( pri, "%s", buffer );
+#pragma convlit(resume)
+       va_end( vl );
+}
+#endif
index 00ad6869e7250a485b25e0c579c5f40a12150a15..24880ab4f9c566e6067a84db1f5a836f944636da 100644 (file)
@@ -186,7 +186,12 @@ do_abandon(
                        ld->ld_errno = LDAP_NO_MEMORY;
 
                } else {
-                       LDAP_NEXT_MSGID(ld, i);
+       /*
+        * We already have the mutex in LDAP_R_COMPILE, so
+        * don't try to get it again.
+        *              LDAP_NEXT_MSGID(ld, i);
+        */
+                       i = ++(ld)->ld_msgid;
 #ifdef LDAP_CONNECTIONLESS
                        if ( LDAP_IS_UDP(ld) ) {
                            err = ber_write( ber, ld->ld_options.ldo_peer,
index 384f0d1e9100a153bc292ee7464d593fda2a0de4..6cc4861ef5461294fd210e751c9938cbfae280a5 100644 (file)
@@ -49,23 +49,23 @@ ldap_pvt_thread_mutex_t ldap_int_sasl_mutex;
 * Various Cyrus SASL related stuff.
 */
 
+static const sasl_callback_t client_callbacks[] = {
+#ifdef SASL_CB_GETREALM
+       { SASL_CB_GETREALM, NULL, NULL },
+#endif
+       { SASL_CB_USER, NULL, NULL },
+       { SASL_CB_AUTHNAME, NULL, NULL },
+       { SASL_CB_PASS, NULL, NULL },
+       { SASL_CB_ECHOPROMPT, NULL, NULL },
+       { SASL_CB_NOECHOPROMPT, NULL, NULL },
+       { SASL_CB_LIST_END, NULL, NULL }
+};
+
 int ldap_int_sasl_init( void )
 {
        /* XXX not threadsafe */
        static int sasl_initialized = 0;
 
-       static sasl_callback_t client_callbacks[] = {
-#ifdef SASL_CB_GETREALM
-               { SASL_CB_GETREALM, NULL, NULL },
-#endif
-               { SASL_CB_USER, NULL, NULL },
-               { SASL_CB_AUTHNAME, NULL, NULL },
-               { SASL_CB_PASS, NULL, NULL },
-               { SASL_CB_ECHOPROMPT, NULL, NULL },
-               { SASL_CB_NOECHOPROMPT, NULL, NULL },
-               { SASL_CB_LIST_END, NULL, NULL }
-       };
-
 #ifdef HAVE_SASL_VERSION
        /* stringify the version number, sasl.h doesn't do it for us */
 #define VSTR0(maj, min, pat)   #maj "." #min "." #pat
@@ -118,7 +118,7 @@ int ldap_int_sasl_init( void )
        ldap_pvt_thread_mutex_init( &ldap_int_sasl_mutex );
 #endif
 
-       if ( sasl_client_init( client_callbacks ) == SASL_OK ) {
+       if ( sasl_client_init( NULL ) == SASL_OK ) {
                sasl_initialized = 1;
                return 0;
        }
@@ -506,9 +506,9 @@ ldap_int_sasl_open(
 
 #if SASL_VERSION_MAJOR >= 2
        rc = sasl_client_new( "ldap", host, NULL, NULL,
-               NULL, 0, &ctx );
+               client_callbacks, 0, &ctx );
 #else
-       rc = sasl_client_new( "ldap", host, NULL,
+       rc = sasl_client_new( "ldap", host, client_callbacks,
                SASL_SECURITY_LAYER, &ctx );
 #endif
 
index deb583eeb71cc4b54183d4fbba41bf592b0eb069..fd7c9b66134cf0d29b32d4bbdf73f1607c7da439 100644 (file)
@@ -725,6 +725,7 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
        char            **refarray = NULL;
        LDAPConn        *lc;
        int                      rc, count, i, j, id;
+       int                      parent_was_reference;
        LDAPreqinfo  rinfo;
 
        ld->ld_errno = LDAP_SUCCESS;    /* optimistic */
@@ -760,6 +761,11 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
                goto done;
        }
 
+       /* check if parent request was a search reference */
+       parent_was_reference = ( lr->lr_parent &&
+               lr->lr_parent->lr_res_msgtype == LDAP_RES_SEARCH_REFERENCE ) ?
+               1 : 0;
+               
        /* find original request */
        for ( origreq = lr;
                origreq->lr_parent != NULL;
@@ -890,7 +896,8 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char *
                ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
 #endif
                rc = ldap_send_server_request( ld, ber, id,
-                       origreq, srv, NULL, &rinfo );
+                       (sref && !parent_was_reference) ? origreq : lr,
+                       srv, NULL, &rinfo );
 #ifdef LDAP_R_COMPILE
                ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
 #endif
index ac780b9d4b743e5ae1c73bbfa200bc06f89a6ca9..e00a07d2f0010e6fb00ac861ab403a0479aa2d50 100644 (file)
@@ -783,6 +783,7 @@ static int chk_lanman(
 #endif /* SLAPD_LMHASH */
 
 #ifdef SLAPD_NS_MTA_MD5
+#define NS_MTA_MD5_PASSLEN     64
 static int chk_ns_mta_md5(
        const struct berval *scheme,
        const struct berval *passwd,
@@ -794,7 +795,7 @@ static int chk_ns_mta_md5(
        char buffer[LUTIL_MD5_BYTES*2];
        int i;
 
-       if( passwd->bv_len != LUTIL_MD5_BYTES*2 ) {
+       if( passwd->bv_len != NS_MTA_MD5_PASSLEN ) {
                return 1;
        }
 
index 65cb28d23f728085e0bfbdf4ff5e84640f64145c..23d964deaa3bd45446d27ffc150fdc4c4a1c3d86 100644 (file)
@@ -28,6 +28,7 @@
 #include "back-bdb.h"
 #include "lutil_hash.h"
 
+#ifdef BDB_INDEX_USE_HASH
 /* Pass-thru hash function. Since the indexer is already giving us hash
  * values as keys, we don't need BDB to re-hash them.
  */
@@ -51,6 +52,10 @@ bdb_db_hash(
        }
        return ret;
 }
+#define        BDB_INDEXTYPE   DB_HASH
+#else
+#define        BDB_INDEXTYPE   DB_BTREE
+#endif
 
 int
 bdb_db_cache(
@@ -109,7 +114,9 @@ bdb_db_cache(
        }
 
        rc = db->bdi_db->set_pagesize( db->bdi_db, BDB_PAGESIZE );
+#ifdef BDB_INDEX_USE_HASH
        rc = db->bdi_db->set_h_hash( db->bdi_db, bdb_db_hash );
+#endif
        rc = db->bdi_db->set_flags( db->bdi_db, DB_DUP | DB_DUPSORT );
        rc = db->bdi_db->set_dup_compare( db->bdi_db, bdb_bt_compare );
 
@@ -121,7 +128,7 @@ bdb_db_cache(
 #endif
        rc = DB_OPEN( db->bdi_db,
                file, NULL /* name */,
-               DB_HASH, bdb->bi_db_opflags | DB_CREATE | DB_THREAD,
+               BDB_INDEXTYPE, bdb->bi_db_opflags | DB_CREATE | DB_THREAD,
                bdb->bi_dbenv_mode );
 
        ch_free( file );
index 6cb8907977267cc70a9bad3ed25b46cebb666347..c8e46b6fd33ef51ea43bc2a44472431730ff4fa3 100644 (file)
@@ -51,6 +51,9 @@ bdb_delete( Operation *op, SlapReply *rs )
        LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
        int num_ctrls = 0;
 
+       int     parent_is_glue = 0;
+       int parent_is_leaf = 0;
+
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, ARGS,  "==> bdb_delete: %s\n", op->o_req_dn.bv_val, 0, 0 );
 #else
@@ -80,6 +83,8 @@ retry:        /* transaction retry */
                        rs->sr_text = "internal error";
                        goto return_results;
                }
+               parent_is_glue = 0;
+               parent_is_leaf = 0;
                ldap_pvt_thread_yield();
                bdb_trans_backoff( ++num_retries );
        }
@@ -474,6 +479,39 @@ retry:     /* transaction retry */
                rs->sr_err = LDAP_OTHER;
                goto return_results;
        }
+
+       bdb_cache_find_id( op, lt2, eip->bei_id, &eip, 0, locker, &plock );
+       if ( eip ) p = eip->bei_e;
+       if ( pdn.bv_len != 0 ) {
+               parent_is_glue = is_entry_glue(p);
+               rs->sr_err = bdb_cache_children( op, lt2, p );
+               if ( rs->sr_err != DB_NOTFOUND ) {
+                       switch( rs->sr_err ) {
+                       case DB_LOCK_DEADLOCK:
+                       case DB_LOCK_NOTGRANTED:
+                               goto retry;
+                       case 0:
+                               break;
+                       default:
+#ifdef NEW_LOGGING
+                               LDAP_LOG ( OPERATION, ERR, 
+                                       "<=- bdb_delete: has_children failed %s (%d)\n",
+                                       db_strerror(rs->sr_err), rs->sr_err, 0 );
+#else
+                               Debug(LDAP_DEBUG_ARGS,
+                                       "<=- bdb_delete: has_children failed: %s (%d)\n",
+                                       db_strerror(rs->sr_err), rs->sr_err, 0 );
+#endif
+                               rs->sr_err = LDAP_OTHER;
+                               rs->sr_text = "internal error";
+                               goto return_results;
+                       }
+                       parent_is_leaf = 1;
+               }
+               bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
+               p = NULL;
+       }
+
        if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "txn_commit(2) failed";
@@ -572,6 +610,10 @@ return_results:
                        bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
        }
 
+       if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) {
+               op->o_delete_glue_parent = 1;
+       }
+
 done:
        /* free entry */
        if( e != NULL ) {
index ec57fd92a21a61f2e38fbdc0e6e64b706785e7e7..07764d0bf45dfafbff4018083b5026f450d52b83 100644 (file)
@@ -37,6 +37,7 @@ int bdb_modify_internal(
        Modifications   *ml;
        Attribute       *save_attrs;
        Attribute       *ap;
+       int                     glue_attr_delete = 0;
 
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, ENTRY, "bdb_modify_internal: 0x%08lx: %s\n", 
@@ -54,6 +55,33 @@ int bdb_modify_internal(
        save_attrs = e->e_attrs;
        e->e_attrs = attrs_dup( e->e_attrs );
 
+       for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
+               mod = &ml->sml_mod;
+               switch( mod->sm_op ) {
+               case LDAP_MOD_ADD:
+               case LDAP_MOD_REPLACE:
+                       if ( mod->sm_desc == slap_schema.si_ad_structuralObjectClass ) {
+                       /* sc modify is internally allowed only to make an entry a glue */
+                               glue_attr_delete = 1;
+                       }
+               }
+               if ( glue_attr_delete )
+                       break;
+       }
+
+       if ( glue_attr_delete ) {
+               Attribute       **app = &e->e_attrs;
+               while ( *app != NULL ) {
+                       if ( !is_at_operational( (*app)->a_desc->ad_type )) {
+                               Attribute *save = *app;
+                               *app = (*app)->a_next;
+                               attr_free( save );
+                               continue;
+                       }
+                       app = &(*app)->a_next;
+               }
+       }
+
        for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
                mod = &ml->sml_mod;
 
@@ -78,6 +106,8 @@ int bdb_modify_internal(
                        break;
 
                case LDAP_MOD_DELETE:
+                       if ( glue_attr_delete )
+                               break;
 #ifdef NEW_LOGGING
                        LDAP_LOG ( OPERATION, DETAIL1, 
                                "bdb_modify_internal: delete\n", 0, 0, 0 );
@@ -203,6 +233,10 @@ int bdb_modify_internal(
                        e->e_ocflags = 0;
                }
 
+               if ( glue_attr_delete ) {
+                       e->e_ocflags = 0;
+               }
+
                /* check if modified attribute was indexed
                 * but not in case of NOOP... */
                err = bdb_index_is_indexed( op->o_bd, mod->sm_desc );
index b42281ef74aa357872956a0b0e65e7c3d532fbd2..ecef5038d838e646178be98018fcde95d77b2854 100644 (file)
@@ -70,6 +70,9 @@ bdb_modrdn( Operation *op, SlapReply *rs )
        Entry           *ctxcsn_e;
        int                     ctxcsn_added = 0;
 
+       int parent_is_glue = 0;
+       int parent_is_leaf = 0;
+
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, ENTRY, "==>bdb_modrdn(%s,%s,%s)\n", 
                op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,
@@ -116,6 +119,8 @@ retry:      /* transaction retry */
                        rs->sr_text = "internal error";
                        goto return_results;
                }
+               parent_is_glue = 0;
+               parent_is_leaf = 0;
                ldap_pvt_thread_yield();
                bdb_trans_backoff( ++num_retries );
        }
@@ -952,6 +957,39 @@ retry:     /* transaction retry */
                rs->sr_text = "entry update failed";
                goto return_results;
        }
+
+       bdb_cache_find_id( op, lt2, eip->bei_id, &eip, 0, locker, &plock );
+    if ( eip ) p = eip->bei_e;
+    if ( p_ndn.bv_len != 0 ) {
+        parent_is_glue = is_entry_glue(p);
+        rs->sr_err = bdb_cache_children( op, lt2, p );
+        if ( rs->sr_err != DB_NOTFOUND ) {
+            switch( rs->sr_err ) {
+            case DB_LOCK_DEADLOCK:
+            case DB_LOCK_NOTGRANTED:
+                goto retry;
+            case 0:
+                break;
+            default:
+#ifdef NEW_LOGGING
+                LDAP_LOG ( OPERATION, ERR,
+                    "<=- bdb_modrdn: has_children failed %s (%d)\n",
+                    db_strerror(rs->sr_err), rs->sr_err, 0 );
+#else
+                Debug(LDAP_DEBUG_ARGS,
+                    "<=- bdb_modrdn: has_children failed: %s (%d)\n",
+                    db_strerror(rs->sr_err), rs->sr_err, 0 );
+#endif
+                rs->sr_err = LDAP_OTHER;
+                rs->sr_text = "internal error";
+                goto return_results;
+            }
+            parent_is_leaf = 1;
+        }
+        bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
+        p = NULL;
+    }
+
        if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "txn_commit(2) failed";
@@ -1051,6 +1089,10 @@ return_results:
                TXN_CHECKPOINT( bdb->bi_dbenv,
                        bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
        }
+       
+       if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) {
+               op->o_delete_glue_parent = 1;
+       }
 
 done:
        if( new_dn.bv_val != NULL ) free( new_dn.bv_val );
index 2ec854b91cfc0230eef4394783bc0ed70722ce97..ca4b755e2cb26cc30123d2b5d883c2acd3336cc2 100644 (file)
@@ -655,7 +655,7 @@ dn2entry_retry:
        if ( be_isroot( op->o_bd, &sop->o_ndn ) ) {
                isroot = 1;
        } else {
-               ( void ) get_limits( op->o_bd, &sop->o_ndn, &limit );
+               ( void ) get_limits( op, &sop->o_ndn, &limit );
        }
 
        /* The time/size limits come first because they require very little
@@ -809,10 +809,7 @@ dn2entry_retry:
                        0, 0, 0 );
 #endif
 
-               rs->sr_err = LDAP_SUCCESS;
-               rs->sr_entry = NULL;
-               send_ldap_result( sop, rs );
-               goto done;
+               goto nochange;
        }
 
        /* if not root and candidates exceed to-be-checked entries, abort */
index d2f6a384f27cc51ab5bd9c1e8c4b8758fc6c246f..adf80638185f9d177f7e89177f9877160324cd27 100644 (file)
@@ -45,6 +45,7 @@ ldap_back_add(
        struct berval mdn = { 0, NULL };
        ber_int_t msgid;
        dncookie dc;
+       int isupdate;
 #ifdef LDAP_BACK_PROXY_AUTHZ 
        LDAPControl **ctrls = NULL;
        int rc = LDAP_SUCCESS;
@@ -88,8 +89,10 @@ ldap_back_add(
 #ifdef ENABLE_REWRITE
        dc.ctx = "addDnAttr";
 #endif
+
+       isupdate = be_isupdate( op->o_bd, &op->o_ndn );
        for (i=0, a=op->oq_add.rs_e->e_attrs; a; a=a->a_next) {
-               if ( a->a_desc->ad_type->sat_no_user_mod  ) {
+               if ( !isupdate && a->a_desc->ad_type->sat_no_user_mod  ) {
                        continue;
                }
 
index edba521aadd9554f43bc584899caf4c47f8e4fbc..a11321b5710b15ee504c01f15c523f720b33a680 100644 (file)
@@ -46,6 +46,7 @@ ldap_back_modify(
        struct berval mdn = { 0, NULL };
        ber_int_t msgid;
        dncookie dc;
+       int isupdate;
 #ifdef LDAP_BACK_PROXY_AUTHZ 
        LDAPControl **ctrls = NULL;
 #endif /* LDAP_BACK_PROXY_AUTHZ */
@@ -89,10 +90,12 @@ ldap_back_modify(
 #ifdef ENABLE_REWRITE
        dc.ctx = "modifyAttrDN";
 #endif
+
+       isupdate = be_isupdate( op->o_bd, &op->o_ndn );
        for (i=0, ml=op->oq_modify.rs_modlist; ml; ml=ml->sml_next) {
                int     is_oc = 0;
 
-               if ( ml->sml_desc->ad_type->sat_no_user_mod  ) {
+               if ( !isupdate && ml->sml_desc->ad_type->sat_no_user_mod  ) {
                        continue;
                }
 
index 4dd6d8ccde5f8a9ca833d93a5f38a1480a10cb6d..fac26b544962d51654f03f37e8aac61e2065d372 100644 (file)
@@ -83,7 +83,7 @@ ldap_back_search(
        if ( be_isroot( op->o_bd, &op->o_ndn ) ) {
                isroot = 1;
        } else {
-               ( void ) get_limits( op->o_bd, &op->o_ndn, &limit );
+               ( void ) get_limits( op, &op->o_ndn, &limit );
        }
        
        /* if no time limit requested, rely on remote server limits */
@@ -218,12 +218,13 @@ fail:;
                } else if (rc == LDAP_RES_SEARCH_ENTRY) {
                        Entry ent = {0};
                        struct berval bdn;
+                       int abort = 0;
                        e = ldap_first_entry(lc->ld,res);
-                       if ( ldap_build_entry(op, e, &ent, &bdn,
-                                               LDAP_BUILD_ENTRY_PRIVATE) == LDAP_SUCCESS ) {
+                       if ( ( rc = ldap_build_entry(op, e, &ent, &bdn,
+                                               LDAP_BUILD_ENTRY_PRIVATE)) == LDAP_SUCCESS ) {
                                rs->sr_entry = &ent;
                                rs->sr_attrs = op->oq_search.rs_attrs;
-                               send_search_entry( op, rs );
+                               abort = send_search_entry( op, rs );
                                while (ent.e_attrs) {
                                        Attribute *a;
                                        BerVarray v;
@@ -245,6 +246,10 @@ fail:;
                                        free( ent.e_ndn );
                        }
                        ldap_msgfree(res);
+                       if ( abort ) {
+                               ldap_abandon(lc->ld, msgid);
+                               goto finish;
+                       }
 
                } else if ( rc == LDAP_RES_SEARCH_REFERENCE ) {
                        char            **references = NULL;
index 663c448b5920b68fcb066f621be5b23933a94f28..222f7cf733b9ba4f9f413cef68cc251761f28073 100644 (file)
@@ -152,8 +152,16 @@ int ldbm_initialize( const char* home )
 
        {
                char *version;
+#ifdef HAVE_EBCDIC
+               char v2[1024];
+#endif
                int major, minor, patch;
                version = db_version( &major, &minor, &patch );
+#ifdef HAVE_EBCDIC
+               strcpy( v2, version );
+               __etoa( v2 );
+               version = v2;
+#endif
 
                if( major != DB_VERSION_MAJOR ||
                        minor < DB_VERSION_MINOR )
index c2d78e659dbfec664738d5cf80b1e6b59892baa4..2aefc84714d57872e9f52006b78dfb1fbe9eca91 100644 (file)
@@ -219,7 +219,7 @@ searchit:
                 */
                isroot = 1;
        } else {
-               ( void ) get_limits( op->o_bd, &op->o_ndn, &limit );
+               ( void ) get_limits( op, &op->o_ndn, &limit );
        }
 
        /* if candidates exceed to-be-checked entries, abort */
index a31356471f32f832f3d0fa42ef080ce7da3bfa64..40f1b03dbe59e0fcdf0f0648777d9387ff36b89d 100644 (file)
@@ -103,7 +103,7 @@ meta_back_search( Operation *op, SlapReply *rs )
        if ( be_isroot( op->o_bd, &op->o_ndn ) ) {
                isroot = 1;
        } else {
-               ( void ) get_limits( op->o_bd, &op->o_ndn, &limit );
+               ( void ) get_limits( op, &op->o_ndn, &limit );
        }
 
        /* if no time limit requested, rely on remote server limits */
index ab9ab045a439d56c314cc0986adf519a97303b31..b3336a618e155200a66795ad1e3f41e9ba397fb6 100644 (file)
@@ -30,17 +30,17 @@ insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (2,1,'telephoneNumber','phones.phone','persons,phones','phones.pers_id=persons.id','select add_phone(?,?)','select delete_phone(?,?)',3,0);
 
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (3,1,'givenName','persons.name','persons',NULL,'update persons set name=? where id=?',NULL,3,0);
-insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (6,1,'sn','persons.surname','persons',NULL,'update persons set surname=? where id=?',NULL,3,0);
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (4,1,'sn','persons.surname','persons',NULL,'update persons set surname=? where id=?',NULL,3,0);
 
-insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (4,2,'description','documents.abstract','documents',NULL,NULL,NULL,3,0);
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (5,2,'description','documents.abstract','documents',NULL,NULL,NULL,3,0);
 
-insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (5,2,'documentTitle','documents.title','documents',NULL,NULL,NULL,3,0);
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (6,2,'documentTitle','documents.title','documents',NULL,NULL,NULL,3,0);
 
-insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (6,2,'documentAuthor','documentAuthor.dn','ldap_entries AS documentAuthor,documents,authors_docs,persons','documentAuthor.keyval=persons.id AND documentAuthor.oc_map_id=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',NULL,NULL,3,0);
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (7,2,'documentAuthor','documentAuthor.dn','ldap_entries AS documentAuthor,documents,authors_docs,persons','documentAuthor.keyval=persons.id AND documentAuthor.oc_map_id=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',NULL,NULL,3,0);
        
-insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (7,3,'o','institutes.name','institutes',NULL,NULL,NULL,3,0);
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (8,3,'o','institutes.name','institutes',NULL,NULL,NULL,3,0);
 
-insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (8,1,'documentIdentifier','documentIdentifier.dn','ldap_entries AS documentIdentifier,documents,authors_docs,persons','documentIdentifier.keyval=documents.id AND documentIdentifier.oc_map_id=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',NULL,NULL,3,0);
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (9,1,'documentIdentifier','documentIdentifier.dn','ldap_entries AS documentIdentifier,documents,authors_docs,persons','documentIdentifier.keyval=documents.id AND documentIdentifier.oc_map_id=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',NULL,NULL,3,0);
 
 
 -- entries mapping: each entry must appear in this table, with a unique DN rooted at the database naming context
index d036ea2ea0dc40a0614c80e32e62300edcf06376..65257d0e0fa610d17e88325414d1f2b0a2bb3328 100644 (file)
@@ -1191,7 +1191,7 @@ backsql_search( Operation *op, SlapReply *rs )
        if ( be_isroot( op->o_bd, &op->o_ndn ) ) {
                isroot = 1;
        } else {
-               ( void ) get_limits( op->o_bd, &op->o_ndn, &limit );
+               ( void ) get_limits( op, &op->o_ndn, &limit );
        }
 
        /* The time/size limits come first because they require very little
index dde2b2d27e5668f56da70f8fea70712171c8c99b..21b12c6286fdc8a50b97e95d39787d5829a59266 100644 (file)
@@ -194,7 +194,7 @@ glue_back_response ( Operation *op, SlapReply *rs )
        switch(rs->sr_type) {
        case REP_SEARCH:
                if ( gs->slimit && rs->sr_nentries >= gs->slimit ) {
-                       gs->err = LDAP_SIZELIMIT_EXCEEDED;
+                       rs->sr_err = gs->err = LDAP_SIZELIMIT_EXCEEDED;
                        return -1;
                }
                /* fallthru */
index ce61d3c30d4aa3c0b8910b065f78ed44dee0c1b5..6e2c934847980ae44c92d2f1a0a85e9045a3a991 100644 (file)
@@ -1435,8 +1435,7 @@ int connection_read(ber_socket_t s)
 
 static int
 connection_input(
-       Connection *conn
-)
+       Connection *conn )
 {
        Operation *op;
        ber_tag_t       tag;
@@ -1448,6 +1447,7 @@ connection_input(
        Sockaddr        peeraddr;
        char            *cdn = NULL;
 #endif
+       char *defer = NULL;
 
        if ( conn->c_currentber == NULL &&
                ( conn->c_currentber = ber_alloc()) == NULL )
@@ -1617,28 +1617,34 @@ connection_input(
         * Bind, or if it's closing. Also, don't let any single conn
         * use up all the available threads, and don't execute if we're
         * currently blocked on output. And don't execute if there are
-        * already pending ops, let them go first.
-        *
-        * But always allow Abandon through; it won't cost much.
+        * already pending ops, let them go first.  Abandon operations
+        * get exceptions to some, but not all, cases.
         */
-       if ( tag != LDAP_REQ_ABANDON && (conn->c_conn_state == SLAP_C_BINDING
-               || conn->c_conn_state == SLAP_C_CLOSING
-               || conn->c_n_ops_executing >= connection_pool_max/2
-               || conn->c_n_ops_pending
-               || conn->c_writewaiter))
-       {
+       if (tag != LDAP_REQ_ABANDON && conn->c_conn_state == SLAP_C_CLOSING) {
+               defer = "closing";
+       } else if (tag != LDAP_REQ_ABANDON && conn->c_writewaiter) {
+               defer = "awaiting write";
+       } else if (conn->c_n_ops_executing >= connection_pool_max/2) {
+               defer = "too many executing";
+       } else if (conn->c_conn_state == SLAP_C_BINDING ) {
+               defer = "binding";
+       } else if (tag != LDAP_REQ_ABANDON && conn->c_n_ops_pending) {
+               defer = "pending operations";
+       }
+
+       if( defer ) {
                int max = conn->c_dn.bv_len
                        ? slap_conn_max_pending_auth
                        : slap_conn_max_pending;
 
 #ifdef NEW_LOGGING
                LDAP_LOG( CONNECTION, INFO, 
-                       "connection_input: conn %lu deferring operation\n",
-                       conn->c_connid, 0, 0 );
+                       "connection_input: conn %lu deferring operation: %s\n",
+                       conn->c_connid, defer, 0 );
 #else
                Debug( LDAP_DEBUG_ANY,
-                       "connection_input: conn=%lu deferring operation\n",
-                       conn->c_connid, 0, 0 );
+                       "connection_input: conn=%lu deferring operation: %s\n",
+                       conn->c_connid, defer, 0 );
 #endif
                conn->c_n_ops_pending++;
                LDAP_STAILQ_INSERT_TAIL( &conn->c_pending_ops, op, o_next );
index 7c83c981d8b259143a2ea3b94548e3153482132e..1749c0975c5a5728e2d4cbf5cc2886bb76f28da7 100644 (file)
@@ -46,6 +46,12 @@ do_delete(
 )
 {
        struct berval dn = { 0, NULL };
+       struct berval pdn = { 0, NULL };
+       struct berval org_req_dn = { 0, NULL };
+       struct berval org_req_ndn = { 0, NULL };
+       struct berval org_dn = { 0, NULL };
+       struct berval org_ndn = { 0, NULL };
+       int     org_managedsait;
        int manageDSAit;
 
 #ifdef NEW_LOGGING
@@ -221,7 +227,41 @@ do_delete(
                                cb.sc_next = op->o_callback;
                                op->o_callback = &cb;
                        }
+
                        op->o_bd->be_delete( op, rs );
+
+                       org_req_dn = op->o_req_dn;
+                       org_req_ndn = op->o_req_ndn;
+                       org_dn = op->o_dn;
+                       org_ndn = op->o_ndn;
+                       org_managedsait = get_manageDSAit( op );
+                       op->o_dn = op->o_bd->be_rootdn;
+                       op->o_ndn = op->o_bd->be_rootndn;
+                       op->o_managedsait = 1;
+
+                       while ( rs->sr_err == LDAP_SUCCESS &&
+                                       op->o_delete_glue_parent ) {
+                               op->o_delete_glue_parent = 0;
+                               if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) {
+                                       slap_callback cb = { NULL };
+                                       cb.sc_response = slap_null_cb;
+                                       dnParent( &op->o_req_ndn, &pdn );
+                                       op->o_req_dn = pdn;
+                                       op->o_req_ndn = pdn;
+                                       op->o_callback = &cb;
+                                       op->o_bd->be_delete( op, rs );
+                               } else {
+                                       break;
+                               }
+                       }
+
+                       op->o_managedsait = org_managedsait;
+                       op->o_dn = org_dn;
+                       op->o_ndn = org_ndn;
+                       op->o_req_dn = org_req_dn;
+                       op->o_req_ndn = org_req_ndn;
+                       op->o_delete_glue_parent = 0;
+
 #ifndef SLAPD_MULTIMASTER
                } else {
                        BerVarray defref = NULL;
index 0f17a9cb8484ca775695ac3909c17bb9790d4805..c258ca7e33063c643e57caf2c6b36e0623bdbb6d 100644 (file)
@@ -201,6 +201,18 @@ get_filter(
 
                if( err != LDAP_SUCCESS ) {
                        /* unrecognized attribute description or other error */
+#ifdef NEW_LOGGING
+                       LDAP_LOG( FILTER, ERR, 
+                               "get_filter: conn %d unknown attribute "
+                               "type=%s (%d)\n",
+                               op->o_connid, type.bv_val, err );
+#else
+                       Debug( LDAP_DEBUG_ANY, 
+                               "get_filter: conn %d unknown attribute "
+                               "type=%s (%d)\n",
+                               op->o_connid, type.bv_val, err );
+#endif
+
                        f.f_choice = SLAPD_FILTER_COMPUTED;
                        f.f_result = LDAP_COMPARE_FALSE;
                        err = LDAP_SUCCESS;
@@ -423,6 +435,16 @@ get_ssa(
        rc = slap_bv2ad( &desc, &ssa.sa_desc, text );
 
        if( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( FILTER, ERR, 
+                       "get_ssa: conn %d d unknown attribute type=%s (%d)\n",
+                       op->o_connid, desc.bv_val, rc );
+#else
+               Debug( LDAP_DEBUG_ANY, 
+                       "get_ssa: conn %d unknown attribute type=%s (%d)\n",
+                       op->o_connid, desc.bv_val, rc );
+#endif
+
                /* skip over the rest of this filter */
                for ( tag = ber_first_element( ber, &len, &last );
                        tag != LBER_DEFAULT;
@@ -1031,6 +1053,18 @@ get_simple_vrFilter(
 
                if( err != LDAP_SUCCESS ) {
                        /* unrecognized attribute description or other error */
+#ifdef NEW_LOGGING
+                       LDAP_LOG( FILTER, ERR, 
+                               "get_simple_vrFilter: conn %d unknown "
+                               "attribute type=%s (%d)\n",
+                               op->o_connid, type.bv_val, err );
+#else
+                       Debug( LDAP_DEBUG_ANY, 
+                               "get_simple_vrFilter: conn %d unknown "
+                               "attribute type=%s (%d)\n",
+                               op->o_connid, type.bv_val, err );
+#endif
+
                        vrf.vrf_choice = SLAPD_FILTER_COMPUTED;
                        vrf.vrf_result = LDAP_COMPARE_FALSE;
                        err = LDAP_SUCCESS;
index d5fae775a2b7989d7cfc0973838c184d81a378d3..1ba44b81bac7e6282ce5c21b8b3a15bca4db572e 100644 (file)
 
 int
 get_limits( 
-       Backend                 *be, 
+       Operation               *op,
        struct berval           *ndn, 
        struct slap_limits_set  **limit
 )
 {
        struct slap_limits **lm;
 
-       assert( be );
+       assert( op );
        assert( limit );
 
        /*
         * default values
         */
-       *limit = &be->be_def_limit;
+       *limit = &op->o_bd->be_def_limit;
 
-       if ( be->be_limits == NULL ) {
+       if ( op->o_bd->be_limits == NULL ) {
                return( 0 );
        }
 
-       for ( lm = be->be_limits; lm[0] != NULL; lm++ ) {
-               switch ( lm[0]->lm_type ) {
+       for ( lm = op->o_bd->be_limits; lm[0] != NULL; lm++ ) {
+               unsigned        style = lm[0]->lm_flags & SLAP_LIMITS_MASK;
+               unsigned        type = lm[0]->lm_flags & SLAP_LIMITS_TYPE_MASK;
+
+               switch ( style ) {
                case SLAP_LIMITS_EXACT:
                        if ( ndn->bv_len == 0 ) {
                                break;
                        }
-                       if ( dn_match( &lm[0]->lm_dn_pat, ndn ) ) {
+
+                       if ( type == SLAP_LIMITS_TYPE_GROUP ) {
+                               int     rc;
+
+                               rc = backend_group( op, NULL,
+                                               &lm[0]->lm_pat, ndn,
+                                               lm[0]->lm_group_oc,
+                                               lm[0]->lm_group_ad );
+                               if ( rc == 0 ) {
+                                       *limit = &lm[0]->lm_limits;
+                                       return( 0 );
+                               }
+                       }
+                       
+                       if ( dn_match( &lm[0]->lm_pat, ndn ) ) {
                                *limit = &lm[0]->lm_limits;
                                return( 0 );
                        }
@@ -66,14 +83,14 @@ get_limits(
                        }
 
                        /* ndn shorter than dn_pat */
-                       if ( ndn->bv_len < lm[0]->lm_dn_pat.bv_len ) {
+                       if ( ndn->bv_len < lm[0]->lm_pat.bv_len ) {
                                break;
                        }
-                       d = ndn->bv_len - lm[0]->lm_dn_pat.bv_len;
+                       d = ndn->bv_len - lm[0]->lm_pat.bv_len;
 
                        /* allow exact match for SUBTREE only */
                        if ( d == 0 ) {
-                               if ( lm[0]->lm_type != SLAP_LIMITS_SUBTREE ) {
+                               if ( style != SLAP_LIMITS_SUBTREE ) {
                                        break;
                                }
                        } else {
@@ -84,15 +101,19 @@ get_limits(
                        }
 
                        /* in case of (sub)match ... */
-                       if ( lm[0]->lm_dn_pat.bv_len == ( ndn->bv_len - d )
-                                       && strcmp( lm[0]->lm_dn_pat.bv_val, &ndn->bv_val[d] ) == 0 ) {
+                       if ( lm[0]->lm_pat.bv_len == ( ndn->bv_len - d )
+                                       && strcmp( lm[0]->lm_pat.bv_val,
+                                               &ndn->bv_val[d] ) == 0 )
+                       {
                                /* check for exactly one rdn in case of ONE */
-                               if ( lm[0]->lm_type == SLAP_LIMITS_ONE ) {
+                               if ( style == SLAP_LIMITS_ONE ) {
                                        /*
                                         * if ndn is more that one rdn
                                         * below dn_pat, continue
                                         */
-                                       if ( (size_t) dn_rdnlen( NULL, ndn ) != d - 1 ) {
+                                       if ( (size_t) dn_rdnlen( NULL, ndn )
+                                                       != d - 1 )
+                                       {
                                                break;
                                        }
                                }
@@ -108,8 +129,8 @@ get_limits(
                        if ( ndn->bv_len == 0 ) {
                                break;
                        }
-                       if ( regexec( &lm[0]->lm_dn_regex, ndn->bv_val, 0, NULL, 0 )
-                               == 0 )
+                       if ( regexec( &lm[0]->lm_regex, ndn->bv_val,
+                                               0, NULL, 0 ) == 0 )
                        {
                                *limit = &lm[0]->lm_limits;
                                return( 0 );
@@ -146,23 +167,29 @@ get_limits(
 static int
 add_limits(
        Backend                 *be,
-       int                     type,
+       unsigned                flags,
        const char              *pattern,
+       ObjectClass             *group_oc,
+       AttributeDescription    *group_ad,
        struct slap_limits_set  *limit
 )
 {
        int                     i;
        struct slap_limits      *lm;
+       unsigned                type, style;
        
        assert( be );
        assert( limit );
 
-       switch ( type ) {
+       type = flags & SLAP_LIMITS_TYPE_MASK;
+       style = flags & SLAP_LIMITS_MASK;
+
+       switch ( style ) {
        case SLAP_LIMITS_ANONYMOUS:
        case SLAP_LIMITS_USERS:
        case SLAP_LIMITS_ANY:
                for ( i = 0; be->be_limits && be->be_limits[ i ]; i++ ) {
-                       if ( be->be_limits[ i ]->lm_type == type ) {
+                       if ( be->be_limits[ i ]->lm_flags == style ) {
                                return( -1 );
                        }
                }
@@ -172,19 +199,22 @@ add_limits(
 
        lm = ( struct slap_limits * )ch_calloc( sizeof( struct slap_limits ), 1 );
 
-       switch ( type ) {
+       switch ( style ) {
+       case SLAP_LIMITS_UNDEFINED:
+               style = SLAP_LIMITS_EXACT;
+               /* continue to next cases */
        case SLAP_LIMITS_EXACT:
        case SLAP_LIMITS_ONE:
        case SLAP_LIMITS_SUBTREE:
        case SLAP_LIMITS_CHILDREN:
-               lm->lm_type = type;
+               lm->lm_flags = style | type;
                {
                        int rc;
                        struct berval bv;
                        bv.bv_val = (char *) pattern;
                        bv.bv_len = strlen( pattern );
 
-                       rc = dnNormalize( 0, NULL, NULL, &bv, &lm->lm_dn_pat, NULL );
+                       rc = dnNormalize( 0, NULL, NULL, &bv, &lm->lm_pat, NULL );
                        if ( rc != LDAP_SUCCESS ) {
                                ch_free( lm );
                                return( -1 );
@@ -193,12 +223,11 @@ add_limits(
                break;
                
        case SLAP_LIMITS_REGEX:
-       case SLAP_LIMITS_UNDEFINED:
-               lm->lm_type = SLAP_LIMITS_REGEX;
-               ber_str2bv( pattern, 0, 1, &lm->lm_dn_pat );
-               if ( regcomp( &lm->lm_dn_regex, lm->lm_dn_pat.bv_val, 
+               lm->lm_flags = style | type;
+               ber_str2bv( pattern, 0, 1, &lm->lm_pat );
+               if ( regcomp( &lm->lm_regex, lm->lm_pat.bv_val, 
                                        REG_EXTENDED | REG_ICASE ) ) {
-                       free( lm->lm_dn_pat.bv_val );
+                       free( lm->lm_pat.bv_val );
                        ch_free( lm );
                        return( -1 );
                }
@@ -207,9 +236,18 @@ add_limits(
        case SLAP_LIMITS_ANONYMOUS:
        case SLAP_LIMITS_USERS:
        case SLAP_LIMITS_ANY:
-               lm->lm_type = type;
-               lm->lm_dn_pat.bv_val = NULL;
-               lm->lm_dn_pat.bv_len = 0;
+               lm->lm_flags = style | type;
+               lm->lm_pat.bv_val = NULL;
+               lm->lm_pat.bv_len = 0;
+               break;
+       }
+
+       switch ( type ) {
+       case SLAP_LIMITS_TYPE_GROUP:
+               assert( group_oc );
+               assert( group_ad );
+               lm->lm_group_oc = group_oc;
+               lm->lm_group_ad = group_ad;
                break;
        }
 
@@ -237,10 +275,12 @@ parse_limits(
        char        **argv
 )
 {
-       int     type = SLAP_LIMITS_UNDEFINED;
-       char    *pattern;
-       struct slap_limits_set limit;
-       int     i, rc = 0;
+       int                     flags = SLAP_LIMITS_UNDEFINED;
+       char                    *pattern;
+       struct slap_limits_set  limit;
+       int                     i, rc = 0;
+       ObjectClass             *group_oc = NULL;
+       AttributeDescription    *group_ad = NULL;
 
        assert( be );
 
@@ -292,54 +332,54 @@ parse_limits(
        
        pattern = argv[1];
        if ( strcmp( pattern, "*" ) == 0) {
-               type = SLAP_LIMITS_ANY;
+               flags = SLAP_LIMITS_ANY;
 
        } else if ( strcasecmp( pattern, "anonymous" ) == 0 ) {
-               type = SLAP_LIMITS_ANONYMOUS;
+               flags = SLAP_LIMITS_ANONYMOUS;
 
        } else if ( strcasecmp( pattern, "users" ) == 0 ) {
-               type = SLAP_LIMITS_USERS;
+               flags = SLAP_LIMITS_USERS;
                
-       } else if ( strncasecmp( pattern, "dn", sizeof( "dn") - 1 ) == 0 ) {
-               pattern += 2;
+       } else if ( strncasecmp( pattern, "dn", sizeof( "dn" ) - 1 ) == 0 ) {
+               pattern += sizeof( "dn" ) - 1;
                if ( pattern[0] == '.' ) {
                        pattern++;
                        if ( strncasecmp( pattern, "exact", sizeof( "exact" ) - 1 ) == 0 ) {
-                               type = SLAP_LIMITS_EXACT;
-                               pattern += 5;
+                               flags = SLAP_LIMITS_EXACT;
+                               pattern += sizeof( "exact" ) - 1;
 
-                       } else if ( strncasecmp( pattern, "base", sizeof( "base " ) - 1 ) == 0 ) {
-                               type = SLAP_LIMITS_BASE;
-                               pattern += 4;
+                       } else if ( strncasecmp( pattern, "base", sizeof( "base" ) - 1 ) == 0 ) {
+                               flags = SLAP_LIMITS_BASE;
+                               pattern += sizeof( "base" ) - 1;
 
                        } else if ( strncasecmp( pattern, "one", sizeof( "one" ) - 1 ) == 0 ) {
-                               type = SLAP_LIMITS_ONE;
-                               pattern += 3;
+                               flags = SLAP_LIMITS_ONE;
+                               pattern += sizeof( "one" ) - 1;
 
                        } else if ( strncasecmp( pattern, "subtree", sizeof( "subtree" ) - 1 ) == 0 ) {
-                               type = SLAP_LIMITS_SUBTREE;
-                               pattern += 7;
+                               flags = SLAP_LIMITS_SUBTREE;
+                               pattern += sizeof( "subtree" ) - 1;
 
                        } else if ( strncasecmp( pattern, "children", sizeof( "children" ) - 1 ) == 0 ) {
-                               type = SLAP_LIMITS_CHILDREN;
-                               pattern += 8;
+                               flags = SLAP_LIMITS_CHILDREN;
+                               pattern += sizeof( "children" ) - 1;
 
                        } else if ( strncasecmp( pattern, "regex", sizeof( "regex" ) - 1 ) == 0 ) {
-                               type = SLAP_LIMITS_REGEX;
-                               pattern += 5;
+                               flags = SLAP_LIMITS_REGEX;
+                               pattern += sizeof( "regex" ) - 1;
 
                        /* 
                         * this could be deprecated in favour
                         * of the pattern = "anonymous" form
                         */
                        } else if ( strncasecmp( pattern, "anonymous", sizeof( "anonymous" ) - 1 ) == 0 ) {
-                               type = SLAP_LIMITS_ANONYMOUS;
+                               flags = SLAP_LIMITS_ANONYMOUS;
                                pattern = NULL;
                        }
                }
 
                /* pre-check the data */
-               switch ( type ) {
+               switch ( flags ) {
                case SLAP_LIMITS_ANONYMOUS:
                case SLAP_LIMITS_USERS:
 
@@ -373,15 +413,95 @@ parse_limits(
 
                        /* trim obvious cases */
                        if ( strcmp( pattern, "*" ) == 0 ) {
-                               type = SLAP_LIMITS_ANY;
+                               flags = SLAP_LIMITS_ANY;
                                pattern = NULL;
 
-                       } else if ( ( type == SLAP_LIMITS_REGEX || type == SLAP_LIMITS_UNDEFINED ) 
+                       } else if ( flags == SLAP_LIMITS_REGEX
                                        && strcmp( pattern, ".*" ) == 0 ) {
-                               type = SLAP_LIMITS_ANY;
+                               flags = SLAP_LIMITS_ANY;
                                pattern = NULL;
                        }
                }
+
+       } else if (strncasecmp( pattern, "group", sizeof( "group" ) - 1 ) == 0 ) {
+               pattern += sizeof( "group" ) - 1;
+
+               if ( pattern[0] == '/' ) {
+                       struct berval   oc, ad;
+
+                       oc.bv_val = pattern + 1;
+
+                       ad.bv_val = strchr(pattern, '/');
+                       if ( ad.bv_val != NULL ) {
+                               const char      *text = NULL;
+                               int             rc;
+
+                               oc.bv_len = ad.bv_val - oc.bv_val;
+
+                               ad.bv_val++;
+                               ad.bv_len = strlen( ad.bv_val );
+                               rc = slap_bv2ad( &ad, &group_ad, &text );
+                               if ( rc != LDAP_SUCCESS ) {
+                                       goto no_ad;
+                               }
+
+                               pattern = ad.bv_val + ad.bv_len;
+
+                       } else {
+                               oc.bv_len = strlen( oc.bv_val );
+
+                               pattern = oc.bv_val + oc.bv_len;
+                       }
+
+                       group_oc = oc_bvfind( &oc );
+                       if ( group_oc == NULL ) {
+                               goto no_oc;
+                       }
+               }
+
+               if ( group_oc == NULL ) {
+                       group_oc = oc_find( SLAPD_GROUP_CLASS );
+                       if ( group_oc == NULL ) {
+no_oc:;
+                               return( -1 );
+                       }
+               }
+
+               if ( group_ad == NULL ) {
+                       const char      *text = NULL;
+                       int             rc;
+                       
+                       rc = slap_str2ad( SLAPD_GROUP_ATTR, &group_ad, &text );
+
+                       if ( rc != LDAP_SUCCESS ) {
+no_ad:;
+                               return( -1 );
+                       }
+               }
+
+               flags = SLAP_LIMITS_TYPE_GROUP | SLAP_LIMITS_EXACT;
+
+               if ( pattern[0] != '=' ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( CONFIG, CRIT, 
+                               "%s : line %d: missing '=' in "
+                               "\"group[/objectClass[/attributeType]]"
+                               "=<pattern>\" in "
+                               "\"limits <pattern> <limits>\" line.\n",
+                               fname, lineno, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY,
+                               "%s : line %d: missing '=' in "
+                               "\"group[/objectClass[/attributeType]]"
+                               "=<pattern>\" in "
+                               "\"limits <pattern> <limits>\" line.\n",
+                               fname, lineno, 0 );
+#endif
+                       return( -1 );
+               }
+
+               /* skip '=' (required) */
+               pattern++;
        }
 
        /* get the limits */
@@ -390,12 +510,12 @@ parse_limits(
 
 #ifdef NEW_LOGGING
                        LDAP_LOG( CONFIG, CRIT, 
-                               "%s : line %d: unknown limit type \"%s\" in "
+                               "%s : line %d: unknown limit values \"%s\" in "
                                "\"limits <pattern> <limits>\" line.\n",
                                fname, lineno, argv[i] );
 #else
                        Debug( LDAP_DEBUG_ANY,
-                               "%s : line %d: unknown limit type \"%s\" in "
+                               "%s : line %d: unknown limit values \"%s\" in "
                                "\"limits <pattern> <limits>\" line.\n",
                        fname, lineno, argv[i] );
 #endif
@@ -419,7 +539,7 @@ parse_limits(
                limit.lms_s_hard = limit.lms_s_soft;
        }
        
-       rc = add_limits( be, type, pattern, &limit );
+       rc = add_limits( be, flags, pattern, group_oc, group_ad, &limit );
        if ( rc ) {
 
 #ifdef NEW_LOGGING
index e5b8c182021300520ee8046764a96031ff95a056..04e0c981f1d9f68223826f6471ff6e3f91788f1a 100644 (file)
@@ -382,11 +382,24 @@ int main( int argc, char **argv )
                }
        }
 
+       {
+               char *logName;
+#ifdef HAVE_EBCDIC
+               logName = ch_strdup( serverName );
+               __atoe( logName );
+#else
+               logName = serverName;
+#endif
+
 #ifdef LOG_LOCAL4
-       openlog( serverName, OPENLOG_OPTIONS, syslogUser );
+               openlog( logName, OPENLOG_OPTIONS, syslogUser );
 #elif LOG_DEBUG
-       openlog( serverName, OPENLOG_OPTIONS );
+               openlog( logName, OPENLOG_OPTIONS );
+#endif
+#ifdef HAVE_EBCDIC
+               free( logName );
 #endif
+       }
 
 #ifdef NEW_LOGGING
        LDAP_LOG( SLAPD, INFO, "%s", Versionstr, 0, 0 );
index 87b1068bd3b957597f8ee79e2e365b208fc52cf9..ea8dd0e612ff41e5de32bd1210f4a6c8a1f249bc 100644 (file)
@@ -63,6 +63,13 @@ do_modrdn(
        ber_len_t       length;
        int manageDSAit;
 
+       struct berval pdn = { 0, NULL };
+       struct berval org_req_dn = { 0, NULL };
+       struct berval org_req_ndn = { 0, NULL };
+       struct berval org_dn = { 0, NULL };
+       struct berval org_ndn = { 0, NULL };
+       int     org_managedsait;
+
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_modrdn: begin\n", 0, 0, 0 );
 #else
@@ -373,6 +380,39 @@ do_modrdn(
                        }
                        op->o_bd->be_modrdn( op, rs );
 
+                       if ( op->o_bd->be_delete ) {
+                               org_req_dn = op->o_req_dn;
+                               org_req_ndn = op->o_req_ndn;
+                               org_dn = op->o_dn;
+                               org_ndn = op->o_ndn;
+                               org_managedsait = get_manageDSAit( op );
+                               op->o_dn = op->o_bd->be_rootdn;
+                               op->o_ndn = op->o_bd->be_rootndn;
+                               op->o_managedsait = 1;
+
+                               while ( rs->sr_err == LDAP_SUCCESS &&
+                                               op->o_delete_glue_parent ) {
+                       op->o_delete_glue_parent = 0;
+                                       if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) {
+                                               slap_callback cb = { NULL };
+                                               cb.sc_response = slap_null_cb;
+                                               dnParent( &op->o_req_ndn, &pdn );
+                                               op->o_req_dn = pdn;
+                                               op->o_req_ndn = pdn;
+                                               op->o_callback = &cb;
+                                               op->o_bd->be_delete( op, rs );
+                                       } else {
+                                               break;
+                                       }
+                               }
+                               op->o_managedsait = org_managedsait;
+                   op->o_dn = org_dn;
+                               op->o_ndn = org_ndn;
+                               op->o_req_dn = org_req_dn;
+                               op->o_req_ndn = org_req_ndn;
+                               op->o_delete_glue_parent = 0;
+                       }
+
 #ifndef SLAPD_MULTIMASTER
                } else {
                        BerVarray defref = NULL;
index 88360befb23c6305c3f42c88c03889caadeb0589..add41d81a172eb22550f62ff1bfc59e207c4e939 100644 (file)
@@ -1658,6 +1658,9 @@ proxy_cache_config(
                }
                if ( cm->db.bd_info->bi_db_init( &cm->db ) ) return( 1 );
 
+               /* This type is in use, needs to be opened */
+               cm->db.bd_info->bi_nDB++;
+
                cm->max_entries = atoi( argv[2] );
 
                cm->numattrsets = atoi( argv[3] );
index 05af11059576c141e4f42664071a44e52cd0ae9d..5e30e730e11bae36a31f5ab66dfd8ad1d8cb80d2 100644 (file)
@@ -628,7 +628,7 @@ LDAP_SLAPD_F (int) slap_build_syncUUID_set LDAP_P((
  * limits.c
  */
 LDAP_SLAPD_F (int) get_limits LDAP_P((
-       Backend *be, struct berval *ndn,
+       Operation *op, struct berval *ndn,
        struct slap_limits_set **limit ));
 LDAP_SLAPD_F (int) parse_limits LDAP_P((
        Backend *be, const char *fname, int lineno,
@@ -1105,9 +1105,9 @@ LDAP_SLAPD_V (struct runqueue_s) syncrepl_rq;
 
 LDAP_SLAPD_F (void) init_syncrepl LDAP_P((syncinfo_t *));
 LDAP_SLAPD_F (void*) do_syncrepl LDAP_P((void *, void *));
-LDAP_SLAPD_F (Entry*) syncrepl_message_to_entry LDAP_P((
+LDAP_SLAPD_F (int) syncrepl_message_to_entry LDAP_P((
                                        syncinfo_t *, Operation *, LDAPMessage *,
-                                       Modifications **, int ));
+                                       Modifications **, Entry **, int ));
 LDAP_SLAPD_F (int) syncrepl_entry LDAP_P((
                                        syncinfo_t *, Operation*, Entry*,
                                        Modifications*,int, struct berval*,
index 678c62f91b70fa80e1b3393834f2c1c02155f2b9..63408450132681c643fbf811fafe7ce49614b7aa 100644 (file)
@@ -540,7 +540,7 @@ slap_send_ldap_result( Operation *op, SlapReply *rs )
 
        rs->sr_type = REP_RESULT;
 
-       assert( !LDAP_API_ERROR( rs->sr_err ) && ( rs->sr_err >= 0 ));
+       assert( !LDAP_API_ERROR( rs->sr_err ));
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, 
index d24107b59337b128ffe201b4bb10ad1163f1ae55..0854980bfd338c59ed2042ab460f9e4798b95066 100644 (file)
@@ -1279,24 +1279,37 @@ struct slap_limits_set {
 };
 
 struct slap_limits {
-       int     lm_type;        /* type of pattern */
-#define SLAP_LIMITS_UNDEFINED  0x0000
-#define SLAP_LIMITS_EXACT              0x0001
+       unsigned                lm_flags;       /* type of pattern */
+#define SLAP_LIMITS_UNDEFINED          0x0000U
+#define SLAP_LIMITS_EXACT              0x0001U
 #define SLAP_LIMITS_BASE               SLAP_LIMITS_EXACT
-#define SLAP_LIMITS_ONE                        0x0002
-#define SLAP_LIMITS_SUBTREE            0x0003
-#define SLAP_LIMITS_CHILDREN   0x0004
-#define SLAP_LIMITS_REGEX              0x0005
-#define SLAP_LIMITS_ANONYMOUS  0x0006
-#define SLAP_LIMITS_USERS              0x0007
-#define SLAP_LIMITS_ANY                        0x0008
-       regex_t lm_dn_regex;            /* regex data for REGEX */
+#define SLAP_LIMITS_ONE                        0x0002U
+#define SLAP_LIMITS_SUBTREE            0x0003U
+#define SLAP_LIMITS_CHILDREN           0x0004U
+#define SLAP_LIMITS_REGEX              0x0005U
+#define SLAP_LIMITS_ANONYMOUS          0x0006U
+#define SLAP_LIMITS_USERS              0x0007U
+#define SLAP_LIMITS_ANY                        0x0008U
+#define SLAP_LIMITS_MASK               0x000FU
+
+#define SLAP_LIMITS_TYPE_DN            0x0000U
+#define SLAP_LIMITS_TYPE_GROUP         0x0010U
+#define SLAP_LIMITS_TYPE_MASK          0x00F0U
+
+       regex_t                 lm_regex;       /* regex data for REGEX */
 
        /*
         * normalized DN for EXACT, BASE, ONE, SUBTREE, CHILDREN;
         * pattern for REGEX; NULL for ANONYMOUS, USERS
         */
-       struct berval lm_dn_pat;
+       struct berval           lm_pat;
+
+       /* if lm_flags & SLAP_LIMITS_TYPE_MASK == SLAP_LIMITS_GROUP,
+        * lm_group_oc is objectClass and lm_group_at is attributeType
+        * of member in oc for match; then lm_flags & SLAP_LIMITS_MASK
+        * can only be SLAP_LIMITS_EXACT */
+       ObjectClass             *lm_group_oc;
+       AttributeDescription    *lm_group_ad;
 
        struct slap_limits_set  lm_limits;
 };
@@ -2059,6 +2072,7 @@ typedef struct slap_op {
        ValuesReturnFilter *o_vrFilter; /* ValuesReturnFilter */
 
        int o_nocaching;
+       int     o_delete_glue_parent;
 
 #ifdef LDAP_SLAPI
        void    *o_pb;                  /* NS-SLAPI plugin */
index a77e2c6bcb4dd822456bf8047da1b47ddc0f458f..dd7a5d49a82c003ee5dd0b5195f3f9ddde0fc8c9 100644 (file)
@@ -434,7 +434,7 @@ do_syncrep2(
        int     rc, err, i;
        ber_len_t       len;
 
-       int rc_efree;
+       int rc_efree = 1;
 
        struct berval   *psub;
        Modifications   *modlist = NULL;
@@ -507,12 +507,14 @@ do_syncrep2(
                                                        syncCookie.octet_str[0].bv_val )
                                                slap_parse_sync_cookie( &syncCookie );
                                }
-                               entry = syncrepl_message_to_entry( si, op, msg,
-                                       &modlist, syncstate );
-                               rc_efree = syncrepl_entry( si, op, entry, modlist, syncstate,
-                                                       &syncUUID, &syncCookie_req );
-                               if ( syncCookie.octet_str && syncCookie.octet_str[0].bv_val ) {
-                                       syncrepl_updateCookie( si, op, psub, &syncCookie );
+                               if ( syncrepl_message_to_entry( si, op, msg,
+                                       &modlist, &entry, syncstate ) == LDAP_SUCCESS ) {
+                                       rc_efree = syncrepl_entry( si, op, entry, modlist,
+                                                               syncstate, &syncUUID, &syncCookie_req );
+                                       if ( syncCookie.octet_str &&
+                                                syncCookie.octet_str[0].bv_val ) {
+                                               syncrepl_updateCookie( si, op, psub, &syncCookie );
+                                       }
                                }
                                ldap_controls_free( rctrls );
                                if ( modlist ) {
@@ -570,7 +572,7 @@ do_syncrep2(
                                                &syncCookie_req.ctxcsn[0], &syncCookie.ctxcsn[0], &text );
                                }
                                if ( syncCookie.octet_str && syncCookie.octet_str->bv_val
-                                        && match < 0 ) {
+                                        && match < 0 && err == LDAP_SUCCESS ) {
                                        syncrepl_updateCookie( si, op, psub, &syncCookie );
                                }
                                if ( rctrls ) {
@@ -581,7 +583,8 @@ do_syncrep2(
                                         *      1) err code : LDAP_BUSY ...
                                         *      2) on err policy : stop service, stop sync, retry
                                         */
-                                       if ( refreshDeletes == 0 && match < 0 ) {
+                                       if ( refreshDeletes == 0 && match < 0 &&
+                                                err == LDAP_SUCCESS ) {
                                                syncrepl_del_nonpresent( op, si );
                                        } else {
                                                avl_free( si->si_presentlist, avl_ber_bvfree );
@@ -894,12 +897,13 @@ do_syncrepl(
        return NULL;
 }
 
-Entry*
+int
 syncrepl_message_to_entry(
        syncinfo_t      *si,
        Operation       *op,
        LDAPMessage     *msg,
        Modifications   **modlist,
+       Entry                   **entry,
        int             syncstate
 )
 {
@@ -926,7 +930,7 @@ syncrepl_message_to_entry(
                Debug( LDAP_DEBUG_ANY,
                        "Message type should be entry (%d)", ldap_msgtype( msg ), 0, 0 );
 #endif
-               return NULL;
+               return -1;
        }
 
        op->o_tag = LDAP_REQ_ADD;
@@ -941,7 +945,7 @@ syncrepl_message_to_entry(
                Debug( LDAP_DEBUG_ANY,
                        "syncrepl_message_to_entry : dn get failed (%d)", rc, 0, 0 );
 #endif
-               return NULL;
+               return rc;
        }
 
        dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx );
@@ -952,10 +956,15 @@ syncrepl_message_to_entry(
 
        if ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_DELETE )
        {
-               return NULL;
+               return LDAP_SUCCESS;
+       }
+
+       if ( entry == NULL ) {
+               return -1;
        }
 
        e = ( Entry * ) ch_calloc( 1, sizeof( Entry ) );
+       *entry = e;
        e->e_name = op->o_req_dn;
        e->e_nname = op->o_req_ndn;
 
@@ -1020,7 +1029,7 @@ done:
                e = NULL;
        }
 
-       return e;
+       return rc;
 }
 
 int
@@ -1046,6 +1055,13 @@ syncrepl_entry(
        int ret = LDAP_SUCCESS;
        const char *text;
 
+       struct berval pdn = { 0, NULL };
+       struct berval org_req_dn = { 0, NULL };
+       struct berval org_req_ndn = { 0, NULL };
+       struct berval org_dn = { 0, NULL };
+       struct berval org_ndn = { 0, NULL };
+       int     org_managedsait;
+
        if (( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD ))
        {
                syncuuid_bv = ber_dupbv( NULL, syncUUID );
@@ -1113,6 +1129,39 @@ syncrepl_entry(
                op->o_req_ndn = si->si_syncUUID_ndn;
                op->o_tag = LDAP_REQ_DELETE;
                rc = be->be_delete( op, &rs );
+
+               org_req_dn = op->o_req_dn;
+               org_req_ndn = op->o_req_ndn;
+               org_dn = op->o_dn;
+               org_ndn = op->o_ndn;
+               org_managedsait = get_manageDSAit( op );
+               op->o_dn = op->o_bd->be_rootdn;
+               op->o_ndn = op->o_bd->be_rootndn;
+               op->o_managedsait = 1;
+
+               while ( rs.sr_err == LDAP_SUCCESS &&
+                               op->o_delete_glue_parent ) {
+                       op->o_delete_glue_parent = 0;
+                       if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) {
+                               slap_callback cb = { NULL };
+                               cb.sc_response = slap_null_cb;
+                               dnParent( &op->o_req_ndn, &pdn );
+                               op->o_req_dn = pdn;
+                               op->o_req_ndn = pdn;
+                               op->o_callback = &cb;
+                               op->o_bd->be_delete( op, &rs );
+                       } else {
+                               break;
+                   }
+               }
+
+               op->o_managedsait = org_managedsait;
+               op->o_dn = org_dn;
+               op->o_ndn = org_ndn;
+               op->o_req_dn = org_req_dn;
+               op->o_req_ndn = org_req_ndn;
+               op->o_delete_glue_parent = 0;
+
                op->o_no_psearch = 0;
        }
 
@@ -1121,7 +1170,8 @@ syncrepl_entry(
        case LDAP_SYNC_MODIFY:
                if ( rc == LDAP_SUCCESS ||
                         rc == LDAP_REFERRAL ||
-                        rc == LDAP_NO_SUCH_OBJECT )
+                        rc == LDAP_NO_SUCH_OBJECT ||
+                        rc == LDAP_NOT_ALLOWED_ON_NONLEAF )
                {
                        attr_delete( &e->e_attrs, slap_schema.si_ad_entryUUID );
                        attr_merge_one( e, slap_schema.si_ad_entryUUID,
@@ -1134,7 +1184,7 @@ syncrepl_entry(
                        rc = be->be_add( op, &rs );
 
                        if ( rc != LDAP_SUCCESS ) {
-                               if ( rc == LDAP_ALREADY_EXISTS ) {      
+                               if ( rc == LDAP_ALREADY_EXISTS ) {
                                        op->o_tag = LDAP_REQ_MODIFY;
                                        op->orm_modlist = modlist;
                                        op->o_req_dn = e->e_name;
@@ -1215,6 +1265,12 @@ done :
        return ret;
 }
 
+static struct berval gcbva[] = {
+       BER_BVC("top"),
+       BER_BVC("glue"),
+       BER_BVNULL
+};
+
 static void
 syncrepl_del_nonpresent(
        Operation *op,
@@ -1225,6 +1281,20 @@ syncrepl_del_nonpresent(
        slap_callback   cb = { NULL };
        SlapReply       rs = {REP_RESULT};
        struct nonpresent_entry *np_list, *np_prev;
+       int rc;
+       Modifications *ml;
+       Modifications *mlnext;
+       Modifications *mod;
+       Modifications *modlist = NULL;
+       Modifications **modtail = &modlist;
+       Attribute       *attr;
+
+       struct berval pdn = { 0, NULL };
+       struct berval org_req_dn = { 0, NULL };
+       struct berval org_req_ndn = { 0, NULL };
+       struct berval org_dn = { 0, NULL };
+       struct berval org_ndn = { 0, NULL };
+       int     org_managedsait;
 
        op->o_req_dn = si->si_base;
        op->o_req_ndn = si->si_base;
@@ -1244,7 +1314,9 @@ syncrepl_del_nonpresent(
        op->ors_filterstr = si->si_filterstr;
 
        op->o_nocaching = 1;
+       op->o_managedsait = 0;
        be->be_search( op, &rs );
+       op->o_managedsait = 1;
        op->o_nocaching = 0;
 
        if ( op->ors_filter ) filter_free_x( op, op->ors_filter );
@@ -1261,7 +1333,69 @@ syncrepl_del_nonpresent(
                        cb.sc_private = si;
                        op->o_req_dn = *np_prev->npe_name;
                        op->o_req_ndn = *np_prev->npe_nname;
-                       op->o_bd->be_delete( op, &rs );
+                       rc = op->o_bd->be_delete( op, &rs );
+
+                       if ( rc == LDAP_NOT_ALLOWED_ON_NONLEAF ) {
+                               mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
+                               mod->sml_op = LDAP_MOD_REPLACE;
+                               mod->sml_desc = slap_schema.si_ad_objectClass;
+                               mod->sml_type = mod->sml_desc->ad_cname;
+                               mod->sml_bvalues = &gcbva[0];
+                               *modtail = mod;
+                               modtail = &mod->sml_next;
+
+                               mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ));
+                               mod->sml_op = LDAP_MOD_REPLACE;
+                               mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
+                               mod->sml_type = mod->sml_desc->ad_cname;
+                               mod->sml_bvalues = &gcbva[1];
+                               *modtail = mod;
+                               modtail = &mod->sml_next;
+
+                               op->o_tag = LDAP_REQ_MODIFY;
+                               op->orm_modlist = modlist;
+
+                               rc = be->be_modify( op, &rs );
+
+                               for ( ml = modlist; ml != NULL; ml = mlnext ) {
+                                       mlnext = ml->sml_next;
+                                       free( ml );
+                               }
+                       }
+
+                       org_req_dn = op->o_req_dn;
+                       org_req_ndn = op->o_req_ndn;
+                       org_dn = op->o_dn;
+                       org_ndn = op->o_ndn;
+                       org_managedsait = get_manageDSAit( op );
+                       op->o_dn = op->o_bd->be_rootdn;
+                       op->o_ndn = op->o_bd->be_rootndn;
+                       op->o_managedsait = 1;
+
+                       while ( rs.sr_err == LDAP_SUCCESS &&
+                                       op->o_delete_glue_parent ) {
+                               op->o_delete_glue_parent = 0;
+                               if ( !be_issuffix( op->o_bd, &op->o_req_ndn )) {
+                                       slap_callback cb = { NULL };
+                                       cb.sc_response = slap_null_cb;
+                                       dnParent( &op->o_req_ndn, &pdn );
+                                       op->o_req_dn = pdn;
+                                       op->o_req_ndn = pdn;
+                                       op->o_callback = &cb;
+                                       /* give it a root privil ? */
+                                       op->o_bd->be_delete( op, &rs );
+                               } else {
+                                       break;
+                           }
+                       }
+
+                       op->o_managedsait = org_managedsait;
+                       op->o_dn = org_dn;
+                       op->o_ndn = org_ndn;
+                       op->o_req_dn = org_req_dn;
+                       op->o_req_ndn = org_req_ndn;
+                       op->o_delete_glue_parent = 0;
+
                        ber_bvfree( np_prev->npe_name );
                        ber_bvfree( np_prev->npe_nname );
                        op->o_req_dn.bv_val = NULL;
@@ -1274,11 +1408,6 @@ syncrepl_del_nonpresent(
 }
 
 
-static struct berval gcbva[] = {
-       BER_BVC("top"),
-       BER_BVC("glue")
-};
-
 void
 syncrepl_add_glue(
        Operation* op,
@@ -1348,8 +1477,7 @@ syncrepl_add_glue(
                a->a_vals = ch_calloc( 3, sizeof( struct berval ));
                ber_dupbv( &a->a_vals[0], &gcbva[0] );
                ber_dupbv( &a->a_vals[1], &gcbva[1] );
-               a->a_vals[2].bv_len = 0;
-               a->a_vals[2].bv_val = NULL;
+               ber_dupbv( &a->a_vals[2], &gcbva[2] );
 
                a->a_nvals = a->a_vals;
 
@@ -1361,8 +1489,7 @@ syncrepl_add_glue(
 
                a->a_vals = ch_calloc( 2, sizeof( struct berval ));
                ber_dupbv( &a->a_vals[0], &gcbva[1] );
-               a->a_vals[1].bv_len = 0;
-               a->a_vals[1].bv_val = NULL;
+               ber_dupbv( &a->a_vals[1], &gcbva[2] );
 
                a->a_nvals = a->a_vals;
 
index 838ab1c1c0f0e0d3225432ca3b5855702e521ae8..1aa95059f0691f78c469091b60d585b7e20c6d82 100644 (file)
@@ -232,7 +232,7 @@ int parse_limit( const char *arg, struct slap_limits_set *limit )
        return 0;
 }
 
-int get_limits( Backend *be, struct berval *ndn, struct slap_limits_set **limit )
+int get_limits( Operation *op, struct berval *ndn, struct slap_limits_set **limit )
 {
        return 0;
 }
index 53ce29f483de429549262b337190de903da6c053..527399116ba282725371bc693bdcdb891fa67b76 100644 (file)
@@ -305,7 +305,8 @@ main( int argc, char **argv )
                        }
                }
 
-               if ( update_ctxcsn == SLAP_TOOL_CTXCSN_KEEP ) {
+               if ( update_ctxcsn == SLAP_TOOL_CTXCSN_KEEP &&
+                       ( replica_promotion || replica_demotion )) {
                        if ( is_entry_syncProviderSubentry( e )) { 
                                if ( !LDAP_SLIST_EMPTY( &consumer_subentry )) {
                                        fprintf( stderr, "%s: consumer and provider subentries "
@@ -399,8 +400,9 @@ main( int argc, char **argv )
                        }
                }
 
-               if ( !is_entry_syncProviderSubentry( e ) &&
-                        !is_entry_syncConsumerSubentry( e )) {
+               if (( !is_entry_syncProviderSubentry( e ) &&
+                        !is_entry_syncConsumerSubentry( e )) ||
+                        ( !replica_promotion && !replica_demotion )) {
                        if (!dryrun) {
                                ID id = be->be_entry_put( be, e, &bvtext );
                                if( id == NOID ) {