]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/bconfig.c
Add error checks to prev commit
[openldap] / servers / slapd / bconfig.c
index e0851d35009b29ec60fb0844adfb48453c0170cf..4fb764b3e025023c9ca33eab2e1359f2c9adc7d6 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2005-2011 The OpenLDAP Foundation.
+ * Copyright 2005-2013 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -196,6 +196,7 @@ enum {
        CFG_ACL_ADD,
        CFG_SYNC_SUBENTRY,
        CFG_LTHREADS,
+       CFG_IX_HASH64,
 
        CFG_LAST
 };
@@ -242,7 +243,7 @@ static OidRec OidMacros[] = {
  * OLcfg{Bk|Db}{Oc|At}:0               -> common
  * OLcfg{Bk|Db}{Oc|At}:1               -> back-bdb(/back-hdb)
  * OLcfg{Bk|Db}{Oc|At}:2               -> back-ldif
- * OLcfg{Bk|Db}{Oc|At}:3               -> back-ldap
+ * OLcfg{Bk|Db}{Oc|At}:3               -> back-ldap/meta
  * OLcfg{Bk|Db}{Oc|At}:4               -> back-monitor
  * OLcfg{Bk|Db}{Oc|At}:5               -> back-relay
  * OLcfg{Bk|Db}{Oc|At}:6               -> back-sql(/back-ndb)
@@ -395,19 +396,22 @@ static ConfigTable config_back_cf_table[] = {
        { "include", "file", 2, 2, 0, ARG_MAGIC,
                &config_include, "( OLcfgGlAt:19 NAME 'olcInclude' "
                        "SUP labeledURI )", NULL, NULL },
+       { "index_hash64", "on|off", 2, 2, 0, ARG_ON_OFF|ARG_MAGIC|CFG_IX_HASH64,
+               &config_generic, "( OLcfgGlAt:94 NAME 'olcIndexHash64' "
+                       "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
        { "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_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,
+       { "index_substr_any_len", "len", 2, 2, 0, ARG_UINT|ARG_NONZERO,
                &index_substr_any_len, "( OLcfgGlAt:22 NAME 'olcIndexSubstrAnyLen' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "index_substr_any_step", "step", 2, 2, 0, ARG_INT|ARG_NONZERO,
+       { "index_substr_any_step", "step", 2, 2, 0, ARG_UINT|ARG_NONZERO,
                &index_substr_any_step, "( OLcfgGlAt:23 NAME 'olcIndexSubstrAnyStep' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
-       { "index_intlen", "len", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_IX_INTLEN,
+       { "index_intlen", "len", 2, 2, 0, ARG_UINT|ARG_MAGIC|CFG_IX_INTLEN,
                &config_generic, "( OLcfgGlAt:84 NAME 'olcIndexIntLen' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
        { "lastmod", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_LASTMOD,
@@ -826,8 +830,8 @@ static ConfigOCs cf_ocs[] = {
                 "olcConnMaxPending $ olcConnMaxPendingAuth $ "
                 "olcDisallows $ olcGentleHUP $ olcIdleTimeout $ "
                 "olcIndexSubstrIfMaxLen $ olcIndexSubstrIfMinLen $ "
-                "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexIntLen $ "
-                "olcLocalSSF $ olcLogFile $ olcLogLevel $ "
+                "olcIndexSubstrAnyLen $ olcIndexSubstrAnyStep $ olcIndexHash64 $ "
+                "olcIndexIntLen $ olcLocalSSF $ olcLogFile $ olcLogLevel $ "
                 "olcPasswordCryptSaltFormat $ olcPasswordHash $ olcPidFile $ "
                 "olcPluginLogFile $ olcReadOnly $ olcReferral $ "
                 "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
@@ -911,6 +915,7 @@ typedef struct ServerID {
 } ServerID;
 
 static ServerID *sid_list;
+static ServerID *sid_set;
 
 typedef struct voidList {
        struct voidList *vl_next;
@@ -1198,6 +1203,9 @@ config_generic(ConfigArgs *c) {
                case CFG_SSTR_IF_MIN:
                        c->value_uint = index_substr_if_minlen;
                        break;
+               case CFG_IX_HASH64:
+                       c->value_int = slap_hash64( -1 );
+                       break;
                case CFG_IX_INTLEN:
                        c->value_int = index_intlen;
                        break;
@@ -1362,6 +1370,8 @@ config_generic(ConfigArgs *c) {
                                si; si = *sip, i++ ) {
                                if ( c->valx == -1 || i == c->valx ) {
                                        *sip = si->si_next;
+                                       if ( sid_set == si )
+                                               sid_set = NULL;
                                        ch_free( si );
                                        if ( c->valx >= 0 )
                                                break;
@@ -1375,6 +1385,10 @@ config_generic(ConfigArgs *c) {
                        c->be->be_flags &= ~SLAP_DBFLAG_HIDDEN;
                        break;
 
+               case CFG_IX_HASH64:
+                       slap_hash64( 0 );
+                       break;
+
                case CFG_IX_INTLEN:
                        index_intlen = SLAP_INDEX_INTLEN_DEFAULT;
                        index_intlen_strlen = SLAP_INDEX_INTLEN_STRLEN(
@@ -1793,7 +1807,7 @@ config_generic(ConfigArgs *c) {
                                /* else prev is NULL, append to end of global list */
                        }
                        if(parse_oc(c, &oc, prev)) return(1);
-                       if (!cfn->c_oc_head) cfn->c_oc_head = oc;
+                       if (!cfn->c_oc_head || !c->valx) cfn->c_oc_head = oc;
                        if (cfn->c_oc_tail == prev) cfn->c_oc_tail = oc;
                        }
                        break;
@@ -1826,7 +1840,7 @@ config_generic(ConfigArgs *c) {
                                /* else prev is NULL, append to end of global list */
                        }
                        if(parse_at(c, &at, prev)) return(1);
-                       if (!cfn->c_at_head) cfn->c_at_head = at;
+                       if (!cfn->c_at_head || !c->valx) cfn->c_at_head = at;
                        if (cfn->c_at_tail == prev) cfn->c_at_tail = at;
                        }
                        break;
@@ -1859,7 +1873,7 @@ config_generic(ConfigArgs *c) {
                                /* else prev is NULL, append to end of global list */
                        }
                        if ( parse_syn( c, &syn, prev ) ) return(1);
-                       if ( !cfn->c_syn_head ) cfn->c_syn_head = syn;
+                       if ( !cfn->c_syn_head || !c->valx ) cfn->c_syn_head = syn;
                        if ( cfn->c_syn_tail == prev ) cfn->c_syn_tail = syn;
                        }
                        break;
@@ -1882,6 +1896,11 @@ config_generic(ConfigArgs *c) {
                                        return(1);
                        break;
 
+               case CFG_IX_HASH64:
+                       if ( slap_hash64( c->value_int != 0 ))
+                               return 1;
+                       break;
+
                case CFG_IX_INTLEN:
                        if ( c->value_int < SLAP_INDEX_INTLEN_DEFAULT )
                                c->value_int = SLAP_INDEX_INTLEN_DEFAULT;
@@ -1891,7 +1910,7 @@ config_generic(ConfigArgs *c) {
                        index_intlen_strlen = SLAP_INDEX_INTLEN_STRLEN(
                                index_intlen );
                        break;
-                       
+
                case CFG_SORTVALS: {
                        ADlist *svnew = NULL, *svtail, *sv;
 
@@ -2035,6 +2054,7 @@ sortval_reject:
                                        Debug( LDAP_DEBUG_CONFIG,
                                                "%s: SID=0x%03x\n",
                                                c->log, slap_serverID, 0 );
+                                       sid_set = si;
                                }
                                si->si_next = NULL;
                                si->si_num = num;
@@ -2044,11 +2064,20 @@ sortval_reject:
                                if (( slapMode & SLAP_SERVER_MODE ) && c->argc > 2 ) {
                                        Listener *l = config_check_my_url( c->argv[2], lud );
                                        if ( l ) {
+                                               if ( sid_set ) {
+                                                       ldap_free_urldesc( lud );
+                                                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                                               "<%s> multiple server ID URLs matched, only one is allowed", c->argv[0] );
+                                                       Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+                                                               c->log, c->cr_msg, c->argv[1] );
+                                                       return 1;
+                                               }
                                                slap_serverID = si->si_num;
                                                Debug( LDAP_DEBUG_CONFIG,
                                                        "%s: SID=0x%03x (listener=%s)\n",
                                                        c->log, slap_serverID,
                                                        l->sl_url.bv_val );
+                                               sid_set = si;
                                        }
                                }
                                if ( c->argc > 2 )
@@ -3057,7 +3086,8 @@ config_suffix(ConfigArgs *c)
        }
 #endif
 
-       if (SLAP_DB_ONE_SUFFIX( c->be ) && c->be->be_suffix ) {
+       if (SLAP_DB_ONE_SUFFIX( c->be ) && c->be->be_suffix &&
+               !BER_BVISNULL( &c->be->be_suffix[0] )) {
                snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> Only one suffix is allowed on this %s backend",
                        c->argv[0], c->be->bd_info->bi_type );
                Debug(LDAP_DEBUG_ANY, "%s: %s\n",
@@ -4360,6 +4390,13 @@ done:
                        assert( 0 );
                }
        }
+       if ( rc == 0 && ( slapMode & SLAP_SERVER_MODE ) && sid_list ) {
+               if ( !BER_BVISEMPTY( &sid_list->si_url ) && !sid_set ) {
+                       Debug(LDAP_DEBUG_ANY, "read_config: no serverID / URL match found. "
+                               "Check slapd -h arguments.\n", 0,0,0 );
+                       rc = LDAP_OTHER;
+               }
+       }
        return rc;
 }
 
@@ -4745,9 +4782,34 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e,
                }
        }
 
-       /* count related kids */
-       for (nsibs=0, ce=parent->ce_kids; ce; ce=ce->ce_sibs) {
-               if ( ce->ce_type == ce_type ) nsibs++;
+       /* count related kids.
+        * For entries of type Cft_Misc, only count siblings with same RDN type
+        */
+       if ( ce_type == Cft_Misc ) {
+               rdn.bv_val = e->e_nname.bv_val;
+               ptr1 = strchr( rdn.bv_val, '=' );
+               assert( ptr1 != NULL );
+
+               rdn.bv_len = ptr1 - rdn.bv_val;
+
+               for (nsibs=0, ce=parent->ce_kids; ce; ce=ce->ce_sibs) {
+                       struct berval rdn2;
+                       if ( ce->ce_type != ce_type )
+                               continue;
+
+                       dnRdn( &ce->ce_entry->e_nname, &rdn2 );
+
+                       ptr1 = strchr( rdn2.bv_val, '=' );
+                       assert( ptr1 != NULL );
+
+                       rdn2.bv_len = ptr1 - rdn2.bv_val;
+                       if ( bvmatch( &rdn, &rdn2 ))
+                               nsibs++;
+               }
+       } else {
+               for (nsibs=0, ce=parent->ce_kids; ce; ce=ce->ce_sibs) {
+                       if ( ce->ce_type == ce_type ) nsibs++;
+               }
        }
 
        /* account for -1 frontend */