]> 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 2cd2750bf33fb4451c86801bfce1c0b88531e982..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" },
@@ -526,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 },
@@ -544,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,
@@ -682,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 $ "
@@ -743,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;
@@ -929,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 );
@@ -1077,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;
@@ -1507,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 );
@@ -4960,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 )
@@ -5711,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;