]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/bconfig.c
Ignore attempts to Add cn=schema,cn=config
[openldap] / servers / slapd / bconfig.c
index 57b8438223f8a86afaa2edbf3e86d26c9b77bbd2..7dee51a505810a064e41b55a5a4529edcff6be6b 100644 (file)
@@ -25,6 +25,7 @@
 #include <ac/ctype.h>
 #include <ac/errno.h>
 #include <sys/stat.h>
+#include <ac/unistd.h>
 
 #include "slap.h"
 
@@ -120,6 +121,9 @@ static ConfigDriver config_timelimit;
 static ConfigDriver config_overlay;
 static ConfigDriver config_subordinate; 
 static ConfigDriver config_suffix; 
+#ifdef LDAP_TCP_BUFFER
+static ConfigDriver config_tcp_buffer; 
+#endif /* LDAP_TCP_BUFFER */
 static ConfigDriver config_rootdn;
 static ConfigDriver config_rootpw;
 static ConfigDriver config_restrict;
@@ -186,6 +190,7 @@ enum {
        CFG_IX_INTLEN,
        CFG_SYNTAX,
        CFG_ACL_ADD,
+       CFG_SYNC_SUBENTRY,
 
        CFG_LAST
 };
@@ -374,10 +379,10 @@ static ConfigTable config_back_cf_table[] = {
        { "include", "file", 2, 2, 0, ARG_MAGIC,
                &config_include, "( OLcfgGlAt:19 NAME 'olcInclude' "
                        "SUP labeledURI )", NULL, NULL },
-       { "index_substr_if_minlen", "min", 2, 2, 0, ARG_INT|ARG_NONZERO|ARG_MAGIC|CFG_SSTR_IF_MIN,
+       { "index_substr_if_minlen", "min", 2, 2, 0, ARG_UINT|ARG_NONZERO|ARG_MAGIC|CFG_SSTR_IF_MIN,
                &config_generic, "( OLcfgGlAt:20 NAME 'olcIndexSubstrIfMinLen' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "index_substr_if_maxlen", "max", 2, 2, 0, ARG_INT|ARG_NONZERO|ARG_MAGIC|CFG_SSTR_IF_MAX,
+       { "index_substr_if_maxlen", "max", 2, 2, 0, ARG_UINT|ARG_NONZERO|ARG_MAGIC|CFG_SSTR_IF_MAX,
                &config_generic, "( OLcfgGlAt:21 NAME 'olcIndexSubstrIfMaxLen' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
        { "index_substr_any_len", "len", 2, 2, 0, ARG_INT|ARG_NONZERO,
@@ -600,10 +605,23 @@ static ConfigTable config_back_cf_table[] = {
                &config_suffix, "( OLcfgDbAt:0.10 NAME 'olcSuffix' "
                        "EQUALITY distinguishedNameMatch "
                        "SYNTAX OMsDN )", NULL, NULL },
+       { "sync_use_subentry", NULL, 0, 0, 0, ARG_ON_OFF|ARG_DB|ARG_MAGIC|CFG_SYNC_SUBENTRY,
+               &config_generic, "( OLcfgDbAt:0.19 NAME 'olcSyncUseSubentry' "
+                       "DESC 'Store sync context in a subentry' "
+                       "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
        { "syncrepl", NULL, 0, 0, 0, ARG_DB|ARG_MAGIC,
                &syncrepl_config, "( OLcfgDbAt:0.11 NAME 'olcSyncrepl' "
                        "EQUALITY caseIgnoreMatch "
                        "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
+       { "tcp-buffer", "[listener=<listener>] [{read|write}=]size", 0, 0, 0,
+#ifndef LDAP_TCP_BUFFER
+               ARG_IGNORED, NULL,
+#else /* LDAP_TCP_BUFFER */
+               ARG_MAGIC, &config_tcp_buffer,
+#endif /* LDAP_TCP_BUFFER */
+                       "( OLcfgGlAt:90 NAME 'olcTCPBuffer' "
+                       "DESC 'Custom TCP buffer size' "
+                       "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "threads", "count", 2, 2, 0,
 #ifdef NO_THREADS
                ARG_IGNORED, NULL,
@@ -772,6 +790,7 @@ static ConfigOCs cf_ocs[] = {
                 "olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
                 "olcSecurity $ olcServerID $ olcSizeLimit $ "
                 "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ "
+                "olcTCPBuffer $ "
                 "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
                 "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
                 "olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
@@ -801,7 +820,7 @@ static ConfigOCs cf_ocs[] = {
                 "olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ "
                 "olcReplicaArgsFile $ olcReplicaPidFile $ olcReplicationInterval $ "
                 "olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
-                "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncrepl $ "
+                "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncUseSubentry $ olcSyncrepl $ "
                 "olcTimeLimit $ olcUpdateDN $ olcUpdateRef $ olcMirrorMode $ "
                 "olcMonitoring ) )",
                        Cft_Database, NULL, cfAddDatabase },
@@ -1071,6 +1090,9 @@ config_generic(ConfigArgs *c) {
                case CFG_LASTMOD:
                        c->value_int = (SLAP_NOLASTMOD(c->be) == 0);
                        break;
+               case CFG_SYNC_SUBENTRY:
+                       c->value_int = (SLAP_SYNC_SUBENTRY(c->be) != 0);
+                       break;
                case CFG_MIRRORMODE:
                        if ( SLAP_SHADOW(c->be))
                                c->value_int = (SLAP_SINGLE_SHADOW(c->be) == 0);
@@ -1081,10 +1103,10 @@ config_generic(ConfigArgs *c) {
                        c->value_int = (SLAP_DBMONITORING(c->be) != 0);
                        break;
                case CFG_SSTR_IF_MAX:
-                       c->value_int = index_substr_if_maxlen;
+                       c->value_uint = index_substr_if_maxlen;
                        break;
                case CFG_SSTR_IF_MIN:
-                       c->value_int = index_substr_if_minlen;
+                       c->value_uint = index_substr_if_minlen;
                        break;
                case CFG_IX_INTLEN:
                        c->value_int = index_intlen;
@@ -1183,6 +1205,7 @@ config_generic(ConfigArgs *c) {
                case CFG_SSTR_IF_MAX:
                case CFG_SSTR_IF_MIN:
                case CFG_ACL_ADD:
+               case CFG_SYNC_SUBENTRY:
                        break;
 
                /* no-ops, requires slapd restart */
@@ -1770,7 +1793,8 @@ sortval_reject:
                                ServerID *si, **sip;
                                LDAPURLDesc *lud;
                                int num;
-                               if ( lutil_atoi( &num, c->argv[1] ) ||
+                               if (( lutil_atoi( &num, c->argv[1] ) && 
+                                       lutil_atoix( &num, c->argv[1], 16 )) ||
                                        num < 0 || num > SLAP_SYNC_SID_MAX )
                                {
                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
@@ -1815,7 +1839,7 @@ sortval_reject:
                                        BER_BVZERO( &si->si_url );
                                        slap_serverID = num;
                                        Debug( LDAP_DEBUG_CONFIG,
-                                               "%s: SID=%d\n",
+                                               "%s: SID=0x%03x\n",
                                                c->log, slap_serverID, 0 );
                                }
                                si->si_next = NULL;
@@ -1824,66 +1848,13 @@ sortval_reject:
                                *sip = si;
 
                                if (( slapMode & SLAP_SERVER_MODE ) && c->argc > 2 ) {
-                                       Listener **l = slapd_get_listeners();
-                                       int i, isMe = 0;
-
-                                       /* Try a straight compare with Listener strings */
-                                       for ( i=0; l && l[i]; i++ ) {
-                                               if ( !strcasecmp( c->argv[2], l[i]->sl_url.bv_val )) {
-                                                       isMe = 1;
-                                                       break;
-                                               }
-                                       }
-
-                                       /* If hostname is empty, or is localhost, or matches
-                                        * our hostname, this serverID refers to this host.
-                                        * Compare it against listeners and ports.
-                                        */
-                                       if ( !isMe && ( !lud->lud_host || !lud->lud_host[0] ||
-                                               !strncasecmp("localhost", lud->lud_host,
-                                                       STRLENOF("localhost")) ||
-                                               !strcasecmp( global_host, lud->lud_host ))) {
-
-                                               for ( i=0; l && l[i]; i++ ) {
-                                                       LDAPURLDesc *lu2;
-                                                       ldap_url_parse( l[i]->sl_url.bv_val, &lu2 );
-                                                       do {
-                                                               if ( strcasecmp( lud->lud_scheme,
-                                                                       lu2->lud_scheme ))
-                                                                       break;
-                                                               if ( lud->lud_port != lu2->lud_port )
-                                                                       break;
-                                                               /* Listener on ANY address */
-                                                               if ( !lu2->lud_host || !lu2->lud_host[0] ) {
-                                                                       isMe = 1;
-                                                                       break;
-                                                               }
-                                                               /* URL on ANY address */
-                                                               if ( !lud->lud_host || !lud->lud_host[0] ) {
-                                                                       isMe = 1;
-                                                                       break;
-                                                               }
-                                                               /* Listener has specific host, must
-                                                                * match it
-                                                                */
-                                                               if ( !strcasecmp( lud->lud_host,
-                                                                       lu2->lud_host )) {
-                                                                       isMe = 1;
-                                                                       break;
-                                                               }
-                                                       } while(0);
-                                                       ldap_free_urldesc( lu2 );
-                                                       if ( isMe ) {
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                                       if ( isMe ) {
+                                       Listener *l = config_check_my_url( c->argv[2], lud );
+                                       if ( l ) {
                                                slap_serverID = si->si_num;
                                                Debug( LDAP_DEBUG_CONFIG,
-                                                       "%s: SID=%d (listener=%s)\n",
+                                                       "%s: SID=0x%03x (listener=%s)\n",
                                                        c->log, slap_serverID,
-                                                       l[i]->sl_url.bv_val );
+                                                       l->sl_url.bv_val );
                                        }
                                }
                                if ( c->argc > 2 )
@@ -1912,7 +1883,7 @@ sortval_reject:
                        break;
 
                case CFG_MIRRORMODE:
-                       if(!SLAP_SHADOW(c->be)) {
+                       if(c->value_int && !SLAP_SHADOW(c->be)) {
                                snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> database is not a shadow",
                                        c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s\n",
@@ -1939,24 +1910,31 @@ sortval_reject:
                                SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_HIDDEN;
                        break;
 
+               case CFG_SYNC_SUBENTRY:
+                       if (c->value_int)
+                               SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_SYNC_SUBENTRY;
+                       else
+                               SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_SYNC_SUBENTRY;
+                       break;
+
                case CFG_SSTR_IF_MAX:
-                       if (c->value_int < index_substr_if_minlen) {
+                       if (c->value_uint < index_substr_if_minlen) {
                                snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
                                        c->log, c->cr_msg, c->value_int );
                                return(1);
                        }
-                       index_substr_if_maxlen = c->value_int;
+                       index_substr_if_maxlen = c->value_uint;
                        break;
 
                case CFG_SSTR_IF_MIN:
-                       if (c->value_int > index_substr_if_maxlen) {
+                       if (c->value_uint > index_substr_if_maxlen) {
                                snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value", c->argv[0] );
                                Debug(LDAP_DEBUG_ANY, "%s: %s (%d)\n",
                                        c->log, c->cr_msg, c->value_int );
                                return(1);
                        }
-                       index_substr_if_minlen = c->value_int;
+                       index_substr_if_minlen = c->value_uint;
                        break;
 
 #ifdef SLAPD_MODULES
@@ -2032,29 +2010,40 @@ sortval_reject:
                case CFG_REWRITE: {
                        struct berval bv;
                        char *line;
-                       
+                       int rc = 0;
+
+                       if ( c->op == LDAP_MOD_ADD ) {
+                               c->argv++;
+                               c->argc--;
+                       }
                        if(slap_sasl_rewrite_config(c->fname, c->lineno, c->argc, c->argv))
-                               return(1);
+                               rc = 1;
+                       if ( rc == 0 ) {
 
-                       if ( c->argc > 1 ) {
-                               char    *s;
+                               if ( c->argc > 1 ) {
+                                       char    *s;
 
-                               /* quote all args but the first */
-                               line = ldap_charray2str( c->argv, "\" \"" );
-                               ber_str2bv( line, 0, 0, &bv );
-                               s = ber_bvchr( &bv, '"' );
-                               assert( s != NULL );
-                               /* move the trailing quote of argv[0] to the end */
-                               AC_MEMCPY( s, s + 1, bv.bv_len - ( s - bv.bv_val ) );
-                               bv.bv_val[ bv.bv_len - 1 ] = '"';
+                                       /* quote all args but the first */
+                                       line = ldap_charray2str( c->argv, "\" \"" );
+                                       ber_str2bv( line, 0, 0, &bv );
+                                       s = ber_bvchr( &bv, '"' );
+                                       assert( s != NULL );
+                                       /* move the trailing quote of argv[0] to the end */
+                                       AC_MEMCPY( s, s + 1, bv.bv_len - ( s - bv.bv_val ) );
+                                       bv.bv_val[ bv.bv_len - 1 ] = '"';
 
-                       } else {
-                               ber_str2bv( c->argv[ 0 ], 0, 1, &bv );
+                               } else {
+                                       ber_str2bv( c->argv[ 0 ], 0, 1, &bv );
+                               }
+
+                               ber_bvarray_add( &authz_rewrites, &bv );
                        }
-                       
-                       ber_bvarray_add( &authz_rewrites, &bv );
+                       if ( c->op == LDAP_MOD_ADD ) {
+                               c->argv--;
+                               c->argc++;
+                       }
+                       return rc;
                        }
-                       break;
 #endif
 
 
@@ -2325,7 +2314,7 @@ static int
 config_subordinate(ConfigArgs *c)
 {
        int rc = 1;
-       int advertise;
+       int advertise = 0;
 
        switch( c->op ) {
        case SLAP_CONFIG_EMIT:
@@ -2360,13 +2349,359 @@ config_subordinate(ConfigArgs *c)
                        rc = 1;
                        break;
                }
-               advertise = ( c->argc == 2 && !strcasecmp( c->argv[1], "advertise" ));
+
+               if ( c->argc == 2 ) {
+                       if ( strcasecmp( c->argv[1], "advertise" ) == 0 ) {
+                               advertise = 1;
+
+                       } else if ( strcasecmp( c->argv[1], "TRUE" ) != 0 ) {
+                               /* log error */
+                               snprintf( c->cr_msg, sizeof( c->cr_msg),
+                                       "subordinate must be \"TRUE\" or \"advertise\"" );
+                               Debug( LDAP_DEBUG_ANY,
+                                       "%s: suffix \"%s\": %s.\n",
+                                       c->log, c->be->be_suffix[0].bv_val, c->cr_msg );
+                               rc = 1;
+                               break;
+                       }
+               }
+
                rc = glue_sub_add( c->be, advertise, CONFIG_ONLINE_ADD( c ));
                break;
        }
+
+       return rc;
+}
+
+/*
+ * [listener=<listener>] [{read|write}=]<size>
+ */
+
+#ifdef LDAP_TCP_BUFFER
+static BerVarray tcp_buffer;
+int tcp_buffer_num;
+
+#define SLAP_TCP_RMEM (0x1U)
+#define SLAP_TCP_WMEM (0x2U)
+
+static int
+tcp_buffer_parse( struct berval *val, int argc, char **argv,
+               int *size, int *rw, Listener **l )
+{
+       int i, rc = LDAP_SUCCESS;
+       LDAPURLDesc *lud = NULL;
+       char *ptr;
+
+       if ( val != NULL && argv == NULL ) {
+               char *s = val->bv_val;
+
+               argv = ldap_str2charray( s, " \t" );
+               if ( argv == NULL ) {
+                       return LDAP_OTHER;
+               }
+       }
+
+       i = 0;
+       if ( strncasecmp( argv[ i ], "listener=", STRLENOF( "listener=" ) )
+               == 0 )
+       {
+               char *url = argv[ i ] + STRLENOF( "listener=" );
+               
+               if ( ldap_url_parse( url, &lud ) ) {
+                       rc = LDAP_INVALID_SYNTAX;
+                       goto done;
+               }
+
+               *l = config_check_my_url( url, lud );
+               if ( *l == NULL ) {
+                       rc = LDAP_NO_SUCH_ATTRIBUTE;
+                       goto done;
+               }
+
+               i++;
+       }
+
+       ptr = argv[ i ];
+       if ( strncasecmp( ptr, "read=", STRLENOF( "read=" ) ) == 0 ) {
+               *rw |= SLAP_TCP_RMEM;
+               ptr += STRLENOF( "read=" );
+
+       } else if ( strncasecmp( ptr, "write=", STRLENOF( "write=" ) ) == 0 ) {
+               *rw |= SLAP_TCP_WMEM;
+               ptr += STRLENOF( "write=" );
+
+       } else {
+               *rw |= ( SLAP_TCP_RMEM | SLAP_TCP_WMEM );
+       }
+
+       /* accept any base */
+       if ( lutil_atoix( size, ptr, 0 ) ) {
+               rc = LDAP_INVALID_SYNTAX;
+               goto done;
+       }
+
+done:;
+       if ( val != NULL && argv != NULL ) {
+               ldap_charray_free( argv );
+       }
+
+       if ( lud != NULL ) {
+               ldap_free_urldesc( lud );
+       }
+
        return rc;
 }
 
+static int
+tcp_buffer_delete_one( struct berval *val )
+{
+       int rc = 0;
+       int size = -1, rw = 0;
+       Listener *l = NULL;
+
+       rc = tcp_buffer_parse( val, 0, NULL, &size, &rw, &l );
+       if ( rc != 0 ) {
+               return rc;
+       }
+
+       if ( l != NULL ) {
+               int i;
+               Listener **ll = slapd_get_listeners();
+
+               for ( i = 0; ll[ i ] != NULL; i++ ) {
+                       if ( ll[ i ] == l ) break;
+               }
+
+               if ( ll[ i ] == NULL ) {
+                       return LDAP_NO_SUCH_ATTRIBUTE;
+               }
+
+               if ( rw & SLAP_TCP_RMEM ) l->sl_tcp_rmem = -1;
+               if ( rw & SLAP_TCP_WMEM ) l->sl_tcp_wmem = -1;
+
+               for ( i++ ; ll[ i ] != NULL && bvmatch( &l->sl_url, &ll[ i ]->sl_url ); i++ ) {
+                       if ( rw & SLAP_TCP_RMEM ) ll[ i ]->sl_tcp_rmem = -1;
+                       if ( rw & SLAP_TCP_WMEM ) ll[ i ]->sl_tcp_wmem = -1;
+               }
+
+       } else {
+               /* NOTE: this affects listeners without a specific setting,
+                * does not reset all listeners.  If a listener without
+                * specific settings was assigned a buffer because of
+                * a global setting, it will not be reset.  In any case,
+                * buffer changes will only take place at restart. */
+               if ( rw & SLAP_TCP_RMEM ) slapd_tcp_rmem = -1;
+               if ( rw & SLAP_TCP_WMEM ) slapd_tcp_wmem = -1;
+       }
+
+       return rc;
+}
+
+static int
+tcp_buffer_delete( BerVarray vals )
+{
+       int i;
+
+       for ( i = 0; !BER_BVISNULL( &vals[ i ] ); i++ ) {
+               tcp_buffer_delete_one( &vals[ i ] );
+       }
+
+       return 0;
+}
+
+static int
+tcp_buffer_unparse( int size, int rw, Listener *l, struct berval *val )
+{
+       char buf[sizeof("2147483648")], *ptr;
+
+       /* unparse for later use */
+       val->bv_len = snprintf( buf, sizeof( buf ), "%d", size );
+       if ( l != NULL ) {
+               val->bv_len += STRLENOF( "listener=" " " ) + l->sl_url.bv_len;
+       }
+
+       if ( rw != ( SLAP_TCP_RMEM | SLAP_TCP_WMEM ) ) {
+               if ( rw & SLAP_TCP_RMEM ) {
+                       val->bv_len += STRLENOF( "read=" );
+               } else if ( rw & SLAP_TCP_WMEM ) {
+                       val->bv_len += STRLENOF( "write=" );
+               }
+       }
+
+       val->bv_val = SLAP_MALLOC( val->bv_len + 1 );
+
+       ptr = val->bv_val;
+
+       if ( l != NULL ) {
+               ptr = lutil_strcopy( ptr, "listener=" );
+               ptr = lutil_strncopy( ptr, l->sl_url.bv_val, l->sl_url.bv_len );
+               *ptr++ = ' ';
+       }
+
+       if ( rw != ( SLAP_TCP_RMEM | SLAP_TCP_WMEM ) ) {
+               if ( rw & SLAP_TCP_RMEM ) {
+                       ptr = lutil_strcopy( ptr, "read=" );
+               } else if ( rw & SLAP_TCP_WMEM ) {
+                       ptr = lutil_strcopy( ptr, "write=" );
+               }
+       }
+
+       ptr = lutil_strcopy( ptr, buf );
+       *ptr = '\0';
+
+       assert( val->bv_val + val->bv_len == ptr );
+
+       return LDAP_SUCCESS;
+}
+
+static int
+tcp_buffer_add_one( int argc, char **argv )
+{
+       int rc = 0;
+       int size = -1, rw = 0;
+       Listener *l = NULL;
+
+       struct berval val;
+
+       /* parse */
+       rc = tcp_buffer_parse( NULL, argc, argv, &size, &rw, &l );
+       if ( rc != 0 ) {
+               return rc;
+       }
+
+       /* unparse for later use */
+       rc = tcp_buffer_unparse( size, rw, l, &val );
+       if ( rc != LDAP_SUCCESS ) {
+               return rc;
+       }
+
+       /* use parsed values */
+       if ( l != NULL ) {
+               int i;
+               Listener **ll = slapd_get_listeners();
+
+               for ( i = 0; ll[ i ] != NULL; i++ ) {
+                       if ( ll[ i ] == l ) break;
+               }
+
+               if ( ll[ i ] == NULL ) {
+                       return LDAP_NO_SUCH_ATTRIBUTE;
+               }
+
+               /* buffer only applies to TCP listeners;
+                * we do not do any check here, and delegate them
+                * to setsockopt(2) */
+               if ( rw & SLAP_TCP_RMEM ) l->sl_tcp_rmem = size;
+               if ( rw & SLAP_TCP_WMEM ) l->sl_tcp_wmem = size;
+
+               for ( i++ ; ll[ i ] != NULL && bvmatch( &l->sl_url, &ll[ i ]->sl_url ); i++ ) {
+                       if ( rw & SLAP_TCP_RMEM ) ll[ i ]->sl_tcp_rmem = size;
+                       if ( rw & SLAP_TCP_WMEM ) ll[ i ]->sl_tcp_wmem = size;
+               }
+
+       } else {
+               /* NOTE: this affects listeners without a specific setting,
+                * does not set all listeners */
+               if ( rw & SLAP_TCP_RMEM ) slapd_tcp_rmem = size;
+               if ( rw & SLAP_TCP_WMEM ) slapd_tcp_wmem = size;
+       }
+
+       tcp_buffer = SLAP_REALLOC( tcp_buffer, sizeof( struct berval ) * ( tcp_buffer_num + 2 ) );
+       /* append */
+       tcp_buffer[ tcp_buffer_num ] = val;
+
+       tcp_buffer_num++;
+       BER_BVZERO( &tcp_buffer[ tcp_buffer_num ] );
+
+       return rc;
+}
+
+static int
+config_tcp_buffer( ConfigArgs *c )
+{
+       if ( c->op == SLAP_CONFIG_EMIT ) {
+               if ( tcp_buffer == NULL || BER_BVISNULL( &tcp_buffer[ 0 ] ) ) {
+                       return 1;
+               }
+               value_add( &c->rvalue_vals, tcp_buffer );
+               value_add( &c->rvalue_nvals, tcp_buffer );
+               
+       } else if ( c->op == LDAP_MOD_DELETE ) {
+               if ( !c->line  ) {
+                       tcp_buffer_delete( tcp_buffer );
+                       ber_bvarray_free( tcp_buffer );
+                       tcp_buffer = NULL;
+                       tcp_buffer_num = 0;
+
+               } else {
+                       int rc = 0;
+                       int size = -1, rw = 0;
+                       Listener *l = NULL;
+
+                       struct berval val = BER_BVNULL;
+
+                       int i;
+
+                       if ( tcp_buffer_num == 0 ) {
+                               return 1;
+                       }
+
+                       /* parse */
+                       rc = tcp_buffer_parse( NULL, c->argc - 1, &c->argv[ 1 ], &size, &rw, &l );
+                       if ( rc != 0 ) {
+                               return 1;
+                       }
+
+                       /* unparse for later use */
+                       rc = tcp_buffer_unparse( size, rw, l, &val );
+                       if ( rc != LDAP_SUCCESS ) {
+                               return 1;
+                       }
+
+                       for ( i = 0; !BER_BVISNULL( &tcp_buffer[ i ] ); i++ ) {
+                               if ( bvmatch( &tcp_buffer[ i ], &val ) ) {
+                                       break;
+                               }
+                       }
+
+                       if ( BER_BVISNULL( &tcp_buffer[ i ] ) ) {
+                               /* not found */
+                               rc = 1;
+                               goto done;
+                       }
+
+                       tcp_buffer_delete_one( &tcp_buffer[ i ] );
+                       ber_memfree( tcp_buffer[ i ].bv_val );
+                       for ( ; i < tcp_buffer_num; i++ ) {
+                               tcp_buffer[ i ] = tcp_buffer[ i + 1 ];
+                       }
+                       tcp_buffer_num--;
+
+done:;
+                       if ( !BER_BVISNULL( &val ) ) {
+                               SLAP_FREE( val.bv_val );
+                       }
+       
+               }
+
+       } else {
+               int rc;
+
+               rc = tcp_buffer_add_one( c->argc - 1, &c->argv[ 1 ] );
+               if ( rc ) {
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                               "<%s> unable to add value #%d",
+                               c->argv[0], tcp_buffer_num );
+                       Debug( LDAP_DEBUG_ANY, "%s: %s\n",
+                               c->log, c->cr_msg, 0 );
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+#endif /* LDAP_TCP_BUFFER */
+
 static int
 config_suffix(ConfigArgs *c)
 {
@@ -2742,7 +3077,7 @@ static int
 loglevel_init( void )
 {
        slap_verbmasks  lo[] = {
-               { BER_BVC("Any"),       -1 },
+               { BER_BVC("Any"),       (slap_mask_t) LDAP_DEBUG_ANY },
                { BER_BVC("Trace"),     LDAP_DEBUG_TRACE },
                { BER_BVC("Packets"),   LDAP_DEBUG_PACKETS },
                { BER_BVC("Args"),      LDAP_DEBUG_ARGS },
@@ -2894,9 +3229,11 @@ loglevel_print( FILE *out )
 
        fprintf( out, "Installed log subsystems:\n\n" );
        for ( i = 0; !BER_BVISNULL( &loglevel_ops[ i ].word ); i++ ) {
-               fprintf( out, "\t%-30s (%lu)\n",
-                       loglevel_ops[ i ].word.bv_val,
-                       loglevel_ops[ i ].mask );
+               unsigned mask = loglevel_ops[ i ].mask & 0xffffffffUL;
+               fprintf( out,
+                       (mask == ((slap_mask_t) -1 & 0xffffffffUL)
+                        ? "\t%-30s (-1, 0xffffffff)\n" : "\t%-30s (%u, 0x%x)\n"),
+                       loglevel_ops[ i ].word.bv_val, mask, mask );
        }
 
        fprintf( out, "\nNOTE: custom log subsystems may be later installed "
@@ -3123,7 +3460,7 @@ config_updatedn(ConfigArgs *c) {
 }
 
 int
-config_shadow( ConfigArgs *c, int flag )
+config_shadow( ConfigArgs *c, slap_mask_t flag )
 {
        char    *notallowed = NULL;
 
@@ -3142,7 +3479,8 @@ config_shadow( ConfigArgs *c, int flag )
        if ( SLAP_SHADOW(c->be) ) {
                /* if already shadow, only check consistency */
                if ( ( SLAP_DBFLAGS(c->be) & flag ) != flag ) {
-                       Debug( LDAP_DEBUG_ANY, "%s: inconsistent shadow flag 0x%x.\n", c->log, flag, 0 );
+                       Debug( LDAP_DEBUG_ANY, "%s: inconsistent shadow flag 0x%lx.\n",
+                               c->log, flag, 0 );
                        return 1;
                }
 
@@ -4267,6 +4605,7 @@ schema_destroy_one( ConfigArgs *ca, ConfigOCs **colst, int nocs,
 
        ca->valx = -1;
        ca->line = NULL;
+       ca->argc = 1;
        if ( cfn->c_cr_head ) {
                struct berval bv = BER_BVC("olcDitContentRules");
                ad = NULL;
@@ -4366,6 +4705,9 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
                        Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
                                "DN=\"%s\" already exists\n",
                                log_prefix, e->e_name.bv_val, 0 );
+                       /* global schema ignores all writes */
+                       if ( ce->ce_type == Cft_Schema && ce->ce_parent->ce_type == Cft_Global )
+                               return LDAP_COMPARE_TRUE;
                        return LDAP_ALREADY_EXISTS;
                }
        }
@@ -4851,7 +5193,14 @@ out2:;
        ldap_pvt_thread_pool_resume( &connection_pool );
 
 out:;
-       send_ldap_result( op, rs );
+       {       int repl = op->o_dont_replicate;
+               if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
+                       rs->sr_err = LDAP_SUCCESS;
+                       op->o_dont_replicate = 1;
+               }
+               send_ldap_result( op, rs );
+               op->o_dont_replicate = repl;
+       }
        slap_graduate_commit_csn( op );
        return rs->sr_err;
 }
@@ -5082,6 +5431,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
                                        }
                                        ca->line = bv.bv_val;
                                        ca->valx = d->idx[i];
+                                       config_parse_vals(ct, ca, d->idx[i] );
                                        rc = config_del_vals( ct, ca );
                                        if ( rc != LDAP_SUCCESS ) break;
                                        if ( s )
@@ -5093,6 +5443,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
                        } else {
                                ca->valx = -1;
                                ca->line = NULL;
+                               ca->argc = 1;
                                rc = config_del_vals( ct, ca );
                                if ( rc ) rc = LDAP_OTHER;
                                if ( s )
@@ -5139,6 +5490,7 @@ out:
                                        a->a_flags &= ~(SLAP_ATTR_IXDEL|SLAP_ATTR_IXADD);
                                        ca->valx = -1;
                                        ca->line = NULL;
+                                       ca->argc = 1;
                                        config_del_vals( ct, ca );
                                }
                                for ( i=0; !BER_BVISNULL( &s->a_vals[i] ); i++ ) {
@@ -5153,6 +5505,7 @@ out:
                                ct = config_find_table( colst, nocs, a->a_desc, ca );
                                ca->valx = -1;
                                ca->line = NULL;
+                               ca->argc = 1;
                                config_del_vals( ct, ca );
                                s = attr_find( save_attrs, a->a_desc );
                                if ( s ) {