]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/bconfig.c
Fix prev commit, don't generate a new ctxcsn if we're a consumer with
[openldap] / servers / slapd / bconfig.c
index 408f513f0c300faf717b8ab2875d2436fe070251..9ec4b7f10ba52a0ebb69c38179206d8ada26aba3 100644 (file)
@@ -179,6 +179,7 @@ enum {
        CFG_MIRRORMODE,
        CFG_HIDDEN,
        CFG_MONITORING,
+       CFG_SERVERID,
 
        CFG_LAST
 };
@@ -200,6 +201,12 @@ static OidRec OidMacros[] = {
        { "OLcfgBkOc", "OLcfgOc:1" },
        { "OLcfgDbOc", "OLcfgOc:2" },
        { "OLcfgOvOc", "OLcfgOc:3" },
+
+       /* Syntaxes. We should just start using the standard names and
+        * document that they are predefined and available for users
+        * to reference in their own schema. Defining schema without
+        * OID macros is for masochists...
+        */
        { "OMsyn", "1.3.6.1.4.1.1466.115.121.1" },
        { "OMsBoolean", "OMsyn:7" },
        { "OMsDN", "OMsyn:12" },
@@ -344,8 +351,7 @@ static ConfigTable config_back_cf_table[] = {
                &global_idletimeout, "( OLcfgGlAt:18 NAME 'olcIdleTimeout' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
        { "include", "file", 2, 2, 0, ARG_MAGIC,
-               &config_include, "( OLcfgGlAt:19 NAME 'olcInclude' "
-                       "SUP labeledURI )", NULL, NULL },
+               &config_include, NULL, NULL, NULL },
        { "index_substr_if_minlen", "min", 2, 2, 0, ARG_INT|ARG_NONZERO|ARG_MAGIC|CFG_SSTR_IF_MIN,
                &config_generic, "( OLcfgGlAt:20 NAME 'olcIndexSubstrIfMinLen' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
@@ -527,6 +533,10 @@ static ConfigTable config_back_cf_table[] = {
                &config_security, "( OLcfgGlAt:59 NAME 'olcSecurity' "
                        "EQUALITY caseIgnoreMatch "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
+       { "serverID", "number> <[URI]", 2, 3, 0, ARG_MAGIC|CFG_SERVERID,
+               &config_generic, "( OLcfgGlAt:81 NAME 'olcServerID' "
+                       "EQUALITY caseIgnoreMatch "
+                       "SYNTAX OMsDirectoryString )", NULL, NULL },
        { "sizelimit", "limit", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
                &config_sizelimit, "( OLcfgGlAt:60 NAME 'olcSizeLimit' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
@@ -545,7 +555,7 @@ static ConfigTable config_back_cf_table[] = {
                        "SYNTAX OMsDN )", NULL, NULL },
        { "syncrepl", NULL, 0, 0, 0, ARG_DB|ARG_MAGIC,
                &syncrepl_config, "( OLcfgDbAt:0.11 NAME 'olcSyncrepl' "
-                       "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+                       "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
        { "threads", "count", 2, 2, 0,
 #ifdef NO_THREADS
                ARG_IGNORED, NULL,
@@ -646,7 +656,7 @@ static ConfigTable config_back_cf_table[] = {
 };
 
 /* Routines to check if a child can be added to this type */
-static ConfigLDAPadd cfAddSchema, cfAddInclude, cfAddDatabase,
+static ConfigLDAPadd cfAddSchema, cfAddDatabase,
        cfAddBackend, cfAddModule, cfAddOverlay;
 
 /* NOTE: be careful when defining array members
@@ -656,10 +666,9 @@ static ConfigLDAPadd cfAddSchema, cfAddInclude, cfAddDatabase,
 #define CFOC_BACKEND   cf_ocs[3]
 #define CFOC_DATABASE  cf_ocs[4]
 #define CFOC_OVERLAY   cf_ocs[5]
-#define CFOC_INCLUDE   cf_ocs[6]
-#define CFOC_FRONTEND  cf_ocs[7]
+#define CFOC_FRONTEND  cf_ocs[6]
 #ifdef SLAPD_MODULES
-#define CFOC_MODULE    cf_ocs[8]
+#define CFOC_MODULE    cf_ocs[7]
 #endif /* SLAPD_MODULES */
 
 static ConfigOCs cf_ocs[] = {
@@ -684,7 +693,7 @@ static ConfigOCs cf_ocs[] = {
                 "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
                 "olcRootDSE $ "
                 "olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
-                "olcSecurity $ olcSizeLimit $ "
+                "olcSecurity $ olcServerID $ olcSizeLimit $ "
                 "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ "
                 "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ "
                 "olcTLSCACertificatePath $ olcTLSCertificateFile $ "
@@ -724,13 +733,6 @@ static ConfigOCs cf_ocs[] = {
                "DESC 'OpenLDAP Overlay-specific options' "
                "SUP olcConfig STRUCTURAL "
                "MUST olcOverlay )", Cft_Overlay, NULL, cfAddOverlay },
-       { "( OLcfgGlOc:6 "
-               "NAME 'olcIncludeFile' "
-               "DESC 'OpenLDAP configuration include file' "
-               "SUP olcConfig STRUCTURAL "
-               "MUST olcInclude "
-               "MAY ( cn $ olcRootDSE ) )",
-               Cft_Include, NULL, cfAddInclude },
        /* This should be STRUCTURAL like all the other database classes, but
         * that would mean inheriting all of the olcDatabaseConfig attributes,
         * which causes them to be merged twice in config_build_entry.
@@ -752,6 +754,14 @@ static ConfigOCs cf_ocs[] = {
        { NULL, 0, NULL }
 };
 
+typedef struct ServerID {
+       struct ServerID *si_next;
+       struct berval si_url;
+       int si_num;
+} ServerID;
+
+static ServerID *sid_list;
+
 static int
 config_generic(ConfigArgs *c) {
        int i;
@@ -938,6 +948,30 @@ config_generic(ConfigArgs *c) {
                        }
                        }
                        break;
+               case CFG_SERVERID:
+                       if ( sid_list ) {
+                               ServerID *si;
+                               struct berval bv;
+                               char *ptr;
+
+                               for ( si = sid_list; si; si=si->si_next ) {
+                                       if ( !BER_BVISEMPTY( &si->si_url )) {
+                                               bv.bv_len = si->si_url.bv_len + 6;
+                                               bv.bv_val = ch_malloc( bv.bv_len );
+                                               sprintf( bv.bv_val, "%d %s", si->si_num,
+                                                       si->si_url.bv_val );
+                                               ber_bvarray_add( &c->rvalue_vals, &bv );
+                                       } else {
+                                               char buf[5];
+                                               bv.bv_val = buf;
+                                               bv.bv_len = sprintf( buf, "%d", si->si_num );
+                                               value_add_one( &c->rvalue_vals, &bv );
+                                       }
+                               }
+                       } else {
+                               rc = 1;
+                       }
+                       break;
                case CFG_LOGFILE:
                        if ( logfileName )
                                c->value_string = ch_strdup( logfileName );
@@ -1086,6 +1120,23 @@ config_generic(ConfigArgs *c) {
                        logfileName = NULL;
                        break;
 
+               case CFG_SERVERID: {
+                       int i;
+                       ServerID *si, **sip;
+
+                       for ( i=0, si = sid_list, sip = &sid_list;
+                               si; si = *sip, i++ ) {
+                               if ( c->valx == -1 || i == c->valx ) {
+                                       *sip = si->si_next;
+                                       ch_free( si );
+                                       if ( c->valx >= 0 )
+                                               break;
+                               } else {
+                                       sip = &si->si_next;
+                               }
+                       }
+                       }
+                       break;
                case CFG_HIDDEN:
                        c->be->be_flags &= ~SLAP_DBFLAG_HIDDEN;
                        break;
@@ -1516,6 +1567,111 @@ config_generic(ConfigArgs *c) {
                        }
                        break;
 
+               case CFG_SERVERID:
+                       {
+                               ServerID *si, **sip;
+                               LDAPURLDesc *lud;
+                               int num = atoi( c->argv[1] );
+                               if ( num < 0 || num > SLAP_SYNC_SID_MAX ) {
+                                       snprintf( c->msg, sizeof( c->msg ),
+                                               "<%s> illegal server ID", c->argv[0] );
+                                       Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+                                               c->log, c->msg, c->argv[1] );
+                                       return 1;
+                               }
+                               /* only one value allowed if no URL is given */
+                               if ( c->argc > 2 ) {
+                                       int len;
+
+                                       if ( sid_list && BER_BVISEMPTY( &sid_list->si_url )) {
+                                               snprintf( c->msg, sizeof( c->msg ),
+                                                       "<%s> only one server ID allowed now", c->argv[0] );
+                                               Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+                                                       c->log, c->msg, c->argv[1] );
+                                               return 1;
+                                       }
+
+                                       if ( ldap_url_parse( c->argv[2], &lud )) {
+                                               snprintf( c->msg, sizeof( c->msg ),
+                                                       "<%s> invalid URL", c->argv[0] );
+                                               Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+                                                       c->log, c->msg, c->argv[2] );
+                                               return 1;
+                                       }
+                                       len = strlen( c->argv[2] );
+                                       si = ch_malloc( sizeof(ServerID) + len + 1 );
+                                       si->si_url.bv_val = (char *)(si+1);
+                                       si->si_url.bv_len = len;
+                                       strcpy( si->si_url.bv_val, c->argv[3] );
+                               } else {
+                                       if ( sid_list ) {
+                                               snprintf( c->msg, sizeof( c->msg ),
+                                                       "<%s> unqualified server ID not allowed now", c->argv[0] );
+                                               Debug(LDAP_DEBUG_ANY, "%s: %s %s\n",
+                                                       c->log, c->msg, c->argv[1] );
+                                               return 1;
+                                       }
+                                       si = ch_malloc( sizeof(ServerID) );
+                                       slap_serverID = num;
+                               }
+                               si->si_next = NULL;
+                               si->si_num = num;
+                               for ( sip = &sid_list; *sip; sip = &(*sip)->si_next );
+                               *sip = si;
+
+                               if (( slapMode & SLAP_SERVER_MODE ) && c->argc > 2 ) {
+                                       /* If hostname is empty, or is localhost, or matches
+                                        * our hostname, this serverID refers to this host.
+                                        * Compare it against listeners and ports.
+                                        */
+                                       if ( !lud->lud_host || !lud->lud_host[0] ||
+                                               !strncasecmp("localhost", lud->lud_host,
+                                                       STRLENOF("localhost")) ||
+                                               !strcasecmp( global_host, lud->lud_host )) {
+                                               Listener **l = slapd_get_listeners();
+                                               int i;
+
+                                               for ( i=0; l[i]; i++ ) {
+                                                       LDAPURLDesc *lu2;
+                                                       int isMe = 0;
+                                                       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 ) {
+                                                               slap_serverID = si->si_num;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                               if ( c->argc > 2 )
+                                       ldap_free_urldesc( lud );
+                       }
+                       break;
                case CFG_LOGFILE: {
                                FILE *logfile;
                                if ( logfileName ) ch_free( logfileName );
@@ -3019,15 +3175,8 @@ config_include(ConfigArgs *c) {
        ConfigFile *cf;
        ConfigFile *cfsave = cfn;
        ConfigFile *cf2 = NULL;
-       if (c->op == SLAP_CONFIG_EMIT) {
-               if (c->private) {
-                       ConfigFile *cf = c->private;
-                       value_add_one( &c->rvalue_vals, &cf->c_file );
-                       return 0;
-               }
-               return 1;
-       } else if ( c->op == LDAP_MOD_DELETE ) {
-       }
+
+       /* No dynamic config for include files */
        cf = ch_calloc( 1, sizeof(ConfigFile));
        if ( cfn->c_kids ) {
                for (cf2=cfn->c_kids; cf2 && cf2->c_sibs; cf2=cf2->c_sibs) ;
@@ -3811,7 +3960,7 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e,
        if ( ce_type == Cft_Global ) return 0;
        if ( ce_type == Cft_Schema && parent->ce_type == Cft_Global ) return 0;
 
-       if ( ce_type == Cft_Include || ce_type == Cft_Module )
+       if ( ce_type == Cft_Module )
                tailindex = 1;
 
        /* See if the rdn has an index already */
@@ -3895,21 +4044,6 @@ count_ocs( Attribute *oc_at, int *nocs )
        return colst;
 }
 
-static int
-cfAddInclude( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
-{
-       if ( p->ce_type != Cft_Global && p->ce_type != Cft_Include )
-               return LDAP_CONSTRAINT_VIOLATION;
-
-       /* If we're reading from a configdir, don't parse this entry */
-       if ( ca->lineno )
-               return LDAP_COMPARE_TRUE;
-
-       cfn = p->ce_private;
-       ca->private = cfn;
-       return LDAP_SUCCESS;
-}
-
 static int
 cfAddSchema( CfEntryInfo *p, Entry *e, ConfigArgs *ca )
 {
@@ -4026,6 +4160,7 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
                ca->fname = cfdir.bv_val;
                ca->lineno = 1;
        }
+       ca->ca_op = op;
 
        colst = count_ocs( oc_at, &nocs );
 
@@ -4419,6 +4554,7 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
        ca->private = ce->ce_private;
        ca->ca_entry = e;
        ca->fname = "slapd";
+       ca->ca_op = op;
        strcpy( ca->log, "back-config" );
 
        for (ml = op->orm_modlist; ml; ml=ml->sml_next) {
@@ -4989,6 +5125,41 @@ out:
        return 0;
 }
 
+/* no-op, we never free entries */
+int config_entry_release(
+       Operation *op,
+       Entry *e,
+       int rw )
+{
+       return LDAP_SUCCESS;
+}
+
+/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
+ */
+int config_back_entry_get(
+       Operation *op,
+       struct berval *ndn,
+       ObjectClass *oc,
+       AttributeDescription *at,
+       int rw,
+       Entry **ent )
+{
+       CfBackInfo *cfb;
+       CfEntryInfo *ce, *last;
+
+       cfb = (CfBackInfo *)op->o_bd->be_private;
+
+       ce = config_find_base( cfb->cb_root, ndn, &last );
+       if ( ce ) {
+               *ent = ce->ce_entry;
+               if ( *ent && oc && !is_entry_objectclass_or_sub( *ent, oc ) ) {
+                       *ent = NULL;
+               }
+       }
+
+       return ( *ent == NULL ? 1 : 0 );
+}
+
 static void
 config_build_attrs( Entry *e, AttributeType **at, AttributeDescription *ad,
        ConfigTable *ct, ConfigArgs *c )
@@ -5097,6 +5268,7 @@ config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
        attr_merge_normalize_one(e, slap_schema.si_ad_structuralObjectClass, &oc->soc_cname, NULL );
        if ( op && !op->o_noop ) {
                op->ora_e = e;
+               op->ora_modlist = NULL;
                op->o_bd->be_add( op, rs );
                if ( ( rs->sr_err != LDAP_SUCCESS ) 
                                && (rs->sr_err != LDAP_ALREADY_EXISTS) ) {
@@ -5158,34 +5330,6 @@ config_build_schema_inc( ConfigArgs *c, CfEntryInfo *ceparent,
        return 0;
 }
 
-static int
-config_build_includes( ConfigArgs *c, CfEntryInfo *ceparent,
-       Operation *op, SlapReply *rs )
-{
-       Entry *e;
-       int i;
-       ConfigFile *cf = c->private;
-
-       for (i=0; cf; cf=cf->c_sibs, i++) {
-               c->value_dn.bv_val = c->log;
-               c->value_dn.bv_len = snprintf(c->value_dn.bv_val, sizeof( c->log ), "cn=include" SLAP_X_ORDERED_FMT, i);
-               if ( c->value_dn.bv_len >= sizeof( c->log ) ) {
-                       /* FIXME: how can indicate error? */
-                       return -1;
-               }
-               c->private = cf;
-               e = config_build_entry( op, rs, ceparent, c, &c->value_dn,
-                       &CFOC_INCLUDE, NULL );
-               if ( ! e ) {
-                       return -1;
-               } else if ( e && cf->c_kids ) {
-                       c->private = cf->c_kids;
-                       config_build_includes( c, e->e_private, op, rs );
-               }
-       }
-       return 0;
-}
-
 #ifdef SLAPD_MODULES
 
 static int
@@ -5356,15 +5500,6 @@ config_back_db_open( BackendDB *be )
        parent = e;
        ceparent = ce;
 
-       /* Create includeFile nodes */
-       if ( cfb->cb_config->c_kids ) {
-               c.depth = 0;
-               c.private = cfb->cb_config->c_kids;
-               if ( config_build_includes( &c, ceparent, op, &rs ) ) {
-                       return -1;
-               }
-       }
-
 #ifdef SLAPD_MODULES
        /* Create Module nodes... */
        if ( modpaths.mp_loads ) {
@@ -5776,6 +5911,9 @@ config_back_initialize( BackendInfo *bi )
        bi->bi_connection_init = 0;
        bi->bi_connection_destroy = 0;
 
+       bi->bi_entry_release_rw = config_entry_release;
+       bi->bi_entry_get_rw = config_back_entry_get;
+
        bi->bi_tool_entry_open = config_tool_entry_open;
        bi->bi_tool_entry_close = config_tool_entry_close;
        bi->bi_tool_entry_first = config_tool_entry_first;