static ConfigDriver config_security;
static ConfigDriver config_referral;
static ConfigDriver config_loglevel;
-static ConfigDriver config_replica;
static ConfigDriver config_updatedn;
static ConfigDriver config_updateref;
static ConfigDriver config_include;
+static ConfigDriver config_obsolete;
#ifdef HAVE_TLS
static ConfigDriver config_tls_option;
static ConfigDriver config_tls_config;
CFG_DIT,
CFG_ATTR,
CFG_ATOPT,
- CFG_REPLICA_ARGSFILE,
- CFG_REPLICA_PIDFILE,
- CFG_REPLICATIONINTERVAL,
- CFG_REPLOG,
CFG_ROOTDSE,
CFG_LOGFILE,
CFG_PLUGIN,
&config_referral, "( OLcfgGlAt:41 NAME 'olcReferral' "
"SUP labeledURI SINGLE-VALUE )", NULL, NULL },
{ "replica", "host or uri", 2, 0, 0, ARG_DB|ARG_MAGIC,
- &config_replica, "( OLcfgDbAt:0.7 NAME 'olcReplica' "
+ &config_obsolete, "( OLcfgDbAt:0.7 NAME 'olcReplica' "
"EQUALITY caseIgnoreMatch "
"SUP labeledURI X-ORDERED 'VALUES' )", NULL, NULL },
- { "replica-argsfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC|ARG_STRING|CFG_REPLICA_ARGSFILE,
- &config_generic, "( OLcfgGlAt:43 NAME 'olcReplicaArgsFile' "
+ { "replica-argsfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC,
+ &config_obsolete, "( OLcfgGlAt:43 NAME 'olcReplicaArgsFile' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
- { "replica-pidfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC|ARG_STRING|CFG_REPLICA_PIDFILE,
- &config_generic, "( OLcfgGlAt:44 NAME 'olcReplicaPidFile' "
+ { "replica-pidfile", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC,
+ &config_obsolete, "( OLcfgGlAt:44 NAME 'olcReplicaPidFile' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
- { "replicationInterval", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC|ARG_INT|CFG_REPLICATIONINTERVAL,
- &config_generic, "( OLcfgGlAt:45 NAME 'olcReplicationInterval' "
+ { "replicationInterval", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC,
+ &config_obsolete, "( OLcfgGlAt:45 NAME 'olcReplicationInterval' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
- { "replogfile", "filename", 2, 2, 0, ARG_MAY_DB|ARG_MAGIC|ARG_STRING|CFG_REPLOG,
- &config_generic, "( OLcfgGlAt:46 NAME 'olcReplogFile' "
+ { "replogfile", "filename", 2, 2, 0, ARG_MAY_DB|ARG_MAGIC,
+ &config_obsolete, "( OLcfgGlAt:46 NAME 'olcReplogFile' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "require", "features", 2, 0, 7, ARG_MAY_DB|ARG_MAGIC,
&config_requires, "( OLcfgGlAt:47 NAME 'olcRequires' "
rc = (!i);
break;
}
- case CFG_REPLICA_ARGSFILE:
- if ( c->be->be_replica_argsfile )
- c->value_string = ch_strdup( c->be->be_replica_argsfile );
- break;
- case CFG_REPLICA_PIDFILE:
- if ( c->be->be_replica_pidfile )
- c->value_string = ch_strdup( c->be->be_replica_pidfile );
- break;
- case CFG_REPLICATIONINTERVAL:
- if ( c->be->be_replicationinterval > 0 ) {
- c->value_int = c->be->be_replicationinterval;
- } else {
- rc = 1;
- }
- break;
- case CFG_REPLOG:
- if ( c->be->be_replogfile )
- c->value_string = ch_strdup( c->be->be_replogfile );
- break;
case CFG_ROOTDSE: {
ConfigFile *cf = c->private;
if ( cf->c_dseFiles ) {
passwd_salt = NULL;
break;
- case CFG_REPLICA_ARGSFILE:
- ch_free( c->be->be_replica_argsfile );
- c->be->be_replica_argsfile = NULL;
- break;
-
- case CFG_REPLICA_PIDFILE:
- ch_free( c->be->be_replica_pidfile );
- c->be->be_replica_pidfile = NULL;
- break;
-
- case CFG_REPLICATIONINTERVAL:
- c->be->be_replicationinterval = 0;
- break;
-
- case CFG_REPLOG:
- ch_free( c->be->be_replogfile );
- c->be->be_replogfile = NULL;
- break;
-
case CFG_LOGFILE:
ch_free( logfileName );
logfileName = NULL;
}
break;
- case CFG_REPLICA_ARGSFILE:
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica-argsfile\" should not be used "
- "inside monitor database\n",
- c->log, 0, 0);
- /* FIXME: should this be an error? */
- return(0);
- }
-
- if ( c->be->be_replica_argsfile != NULL ) {
- /* FIXME: error? */
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica-argsfile\" already provided; "
- "replacing \"%s\" with \"%s\".\n",
- c->log, c->be->be_replica_argsfile, c->value_string );
- ch_free( c->be->be_replica_argsfile );
- }
-
- c->be->be_replica_argsfile = c->value_string;
- break;
-
- case CFG_REPLICA_PIDFILE:
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica-pidfile\" should not be used "
- "inside monitor database\n",
- c->log, 0, 0);
- /* FIXME: should this be an error? */
- return(0);
- }
-
- if ( c->be->be_replica_pidfile != NULL ) {
- /* FIXME: error? */
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica-pidfile\" already provided; "
- "replacing \"%s\" with \"%s\".\n",
- c->log, c->be->be_replica_pidfile, c->value_string );
- ch_free( c->be->be_replica_pidfile );
- }
-
- c->be->be_replica_pidfile = c->value_string;
- break;
-
- case CFG_REPLICATIONINTERVAL:
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replicationinterval\" should not be used "
- "inside monitor database\n",
- c->log, 0, 0);
- /* FIXME: should this be an error? */
- return(0);
- }
-
- c->be->be_replicationinterval = c->value_int;
- break;
-
- case CFG_REPLOG:
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replogfile\" should not be used "
- "inside monitor database\n",
- c->log, 0, 0);
- /* FIXME: should this be an error? */
- return(0);
- }
-
- if ( c->be->be_replogfile != NULL ) {
- /* FIXME: error? */
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replogfile\" already provided; "
- "replacing \"%s\" with \"%s\".\n",
- c->log, c->be->be_replogfile, c->value_string );
- ch_free( c->be->be_replogfile );
- }
-
- c->be->be_replogfile = c->value_string;
- break;
-
case CFG_ROOTDSE:
if(root_dse_read_file(c->argv[1])) {
snprintf( c->msg, sizeof( c->msg ), "<%s> could not read file", c->argv[0] );
return 1;
}
si = ch_malloc( sizeof(ServerID) );
+ BER_BVZERO( &si->si_url );
slap_serverID = num;
}
si->si_next = NULL;
return ptr;
}
-static void
-replica_unparse( struct slap_replica_info *ri, int i, struct berval *bv )
-{
- int len;
- char *ptr;
- struct berval bc = BER_BVNULL;
- char numbuf[32];
-
- assert( !BER_BVISNULL( &ri->ri_bindconf.sb_uri ) );
-
- BER_BVZERO( bv );
-
- len = snprintf(numbuf, sizeof( numbuf ), SLAP_X_ORDERED_FMT, i );
- if ( len >= sizeof( numbuf ) ) {
- /* FIXME: how can indicate error? */
- return;
- }
-
- if ( ri->ri_nsuffix ) {
- for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
- len += ri->ri_nsuffix[i].bv_len + STRLENOF(" suffix=\"\"");
- }
- }
- if ( ri->ri_attrs ) {
- len += STRLENOF(" attrs");
- if ( ri->ri_exclude ) len++;
- for (i=0; !BER_BVISNULL( &ri->ri_attrs[i].an_name ); i++) {
- len += 1 + ri->ri_attrs[i].an_name.bv_len;
- }
- }
- bindconf_unparse( &ri->ri_bindconf, &bc );
- len += bc.bv_len;
-
- bv->bv_val = ch_malloc(len + 1);
- bv->bv_len = len;
-
- ptr = lutil_strcopy( bv->bv_val, numbuf );
-
- /* start with URI from bindconf */
- assert( !BER_BVISNULL( &bc ) );
- if ( bc.bv_val ) {
- strcpy( ptr, bc.bv_val );
- ch_free( bc.bv_val );
- }
-
- if ( ri->ri_nsuffix ) {
- for (i=0; !BER_BVISNULL( &ri->ri_nsuffix[i] ); i++) {
- ptr = lutil_strcopy( ptr, " suffix=\"" );
- ptr = lutil_strcopy( ptr, ri->ri_nsuffix[i].bv_val );
- *ptr++ = '"';
- }
- }
- if ( ri->ri_attrs ) {
- ptr = lutil_strcopy( ptr, " attrs" );
- if ( ri->ri_exclude ) *ptr++ = '!';
- *ptr++ = '=';
- ptr = anlist_unparse( ri->ri_attrs, ptr, 0 );
- }
-}
-
-static int
-config_replica(ConfigArgs *c) {
- int i, nr = -1;
- char *replicahost = NULL, *replicauri = NULL;
- LDAPURLDesc *ludp;
-
- if (c->op == SLAP_CONFIG_EMIT) {
- if (c->be->be_replica) {
- struct berval bv;
- for (i=0;c->be->be_replica[i]; i++) {
- replica_unparse( c->be->be_replica[i], i, &bv );
- ber_bvarray_add( &c->rvalue_vals, &bv );
- }
- return 0;
- }
- return 1;
- } else if ( c->op == LDAP_MOD_DELETE ) {
- /* FIXME: there is no replica_free function */
- if ( c->valx < 0 ) {
- } else {
- }
- }
- if(SLAP_MONITOR(c->be)) {
- Debug(LDAP_DEBUG_ANY, "%s: "
- "\"replica\" should not be used inside monitor database\n",
- c->log, 0, 0);
- return(0); /* FIXME: should this be an error? */
- }
-
- for(i = 1; i < c->argc; i++) {
- if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
- ber_len_t len;
-
- if ( replicauri ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
- return(1);
- }
-
- replicahost = c->argv[i] + STRLENOF("host=");
- len = strlen( replicahost ) + STRLENOF("ldap://");
- replicauri = ch_malloc( len + 1 );
- snprintf( replicauri, len + 1, "ldap://%s", replicahost );
- replicahost = replicauri + STRLENOF( "ldap://");
- nr = add_replica_info(c->be, replicauri, replicahost);
- break;
- } else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
- ber_len_t len;
-
- if ( replicauri ) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
- return(1);
- }
-
- if(ldap_url_parse(c->argv[i] + STRLENOF("uri="), &ludp) != LDAP_SUCCESS) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
- return(1);
- }
- if(!ludp->lud_host) {
- ldap_free_urldesc(ludp);
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid uri - missing hostname",
- c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
- return(1);
- }
-
- len = strlen(ludp->lud_scheme) + strlen(ludp->lud_host) +
- STRLENOF("://") + 1;
- if (ludp->lud_port != LDAP_PORT) {
- if (ludp->lud_port < 1 || ludp->lud_port > 65535) {
- ldap_free_urldesc(ludp);
- snprintf( c->msg, sizeof( c->msg ), "<%s> invalid port",
- c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
- return(1);
- }
- len += STRLENOF(":65535");
- }
- replicauri = ch_malloc( len );
- replicahost = lutil_strcopy( replicauri, ludp->lud_scheme );
- replicahost = lutil_strcopy( replicahost, "://" );
- if (ludp->lud_port == LDAP_PORT) {
- strcpy( replicahost, ludp->lud_host );
- } else {
- sprintf( replicahost, "%s:%d",ludp->lud_host,ludp->lud_port );
- }
- ldap_free_urldesc(ludp);
- nr = add_replica_info(c->be, replicauri, replicahost);
- break;
- }
- }
- if(i == c->argc) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> missing host or uri", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
- return(1);
- } else if(nr == -1) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unable to add replica", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg,
- replicauri ? replicauri : "" );
- return(1);
- } else {
- for(i = 1; i < c->argc; i++) {
- if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
- /* dealt with separately; don't let it get to bindconf */
- ;
-
- } else if(!strncasecmp(c->argv[i], "host=", STRLENOF("host="))) {
- /* dealt with separately; don't let it get to bindconf */
- ;
-
- } else if(!strncasecmp(c->argv[i], "suffix=", STRLENOF( "suffix="))) {
- switch(add_replica_suffix(c->be, nr, c->argv[i] + STRLENOF("suffix="))) {
- case 1:
- Debug( LDAP_DEBUG_ANY, "%s: "
- "suffix \"%s\" in \"replica\" line is not valid for backend.\n",
- c->log, c->argv[i] + STRLENOF("suffix="), 0);
- return 1;
- break;
- case 2:
- Debug( LDAP_DEBUG_ANY, "%s: "
- "unable to normalize suffix in \"replica\" line.\n",
- c->log, 0, 0);
- return 1;
- break;
- }
-
- } else if (!strncasecmp(c->argv[i], "attr", STRLENOF("attr"))
- || !strncasecmp(c->argv[i], "attrs", STRLENOF("attrs")))
- {
- int exclude = 0;
- char *arg = c->argv[i] + STRLENOF("attr");
- if (arg[0] == 's') {
- arg++;
- } else {
- Debug( LDAP_DEBUG_ANY,
- "%s: \"attr\" "
- "is deprecated (and undocumented); "
- "use \"attrs\" instead.\n",
- c->log, 0, 0 );
- }
- if(arg[0] == '!') {
- arg++;
- exclude = 1;
- }
- if(arg[0] != '=') {
- continue;
- }
- if(add_replica_attrs(c->be, nr, arg + 1, exclude)) {
- snprintf( c->msg, sizeof( c->msg ), "<%s> unknown attribute", c->argv[0] );
- Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
- c->log, c->msg, arg + 1);
- return(1);
- }
- } else if ( bindconf_parse( c->argv[i],
- &c->be->be_replica[nr]->ri_bindconf ) ) {
- return(1);
- }
- }
- }
- return(0);
-}
-
static int
config_updatedn(ConfigArgs *c) {
if (c->op == SLAP_CONFIG_EMIT) {
return(0);
}
+static int
+config_obsolete(ConfigArgs *c) {
+ if (c->op == SLAP_CONFIG_EMIT)
+ return 1;
+
+ snprintf( c->msg, sizeof( c->msg ), "<%s> keyword is obsolete (ignored)",
+ c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0);
+ return(0);
+}
+
static int
config_include(ConfigArgs *c) {
int savelineno = c->lineno;
argv[1] = (char *)dir;
argv[2] = NULL;
c.argv = argv;
+ c.table = Cft_Database;
ct = config_find_keyword( c.be->be_cf_ocs->co_table, &c );
if ( !ct )
}
static ConfigTable *
-config_find_table( ConfigOCs **colst, int nocs, AttributeDescription *ad )
+config_find_table( ConfigOCs **colst, int nocs, AttributeDescription *ad,
+ ConfigArgs *ca )
{
int i, j;
for (j=0; j<nocs; j++) {
for (i=0; colst[j]->co_table[i].name; i++)
- if ( colst[j]->co_table[i].ad == ad )
+ if ( colst[j]->co_table[i].ad == ad ) {
+ ca->table = colst[j]->co_type;
return &colst[j]->co_table[i];
+ }
}
return NULL;
}
op->o_callback = ≻
op->orr_newrdn = *newrdn;
op->orr_nnewrdn = *nnewrdn;
+ op->orr_newSup = NULL;
+ op->orr_nnewSup = NULL;
op->orr_deleteoldrdn = 1;
op->orr_modlist = NULL;
slap_modrdn2mods( op, rs );
{
CfEntryInfo *ce;
int index = -1, gotindex = 0, nsibs, rc = 0;
- int renumber = 0, tailindex = 0, isfrontend = 0;
+ int renumber = 0, tailindex = 0, isfrontend = 0, isconfig = 0;
char *ptr1, *ptr2 = NULL;
struct berval rdn;
/* See if the rdn has an index already */
dnRdn( &e->e_name, &rdn );
- if ( ce_type == Cft_Database && !strncmp( rdn.bv_val + rdn.bv_len -
- STRLENOF("frontend"), "frontend", STRLENOF("frontend") ))
- isfrontend = 1;
+ if ( ce_type == Cft_Database ) {
+ if ( !strncmp( rdn.bv_val + rdn.bv_len - STRLENOF("frontend"),
+ "frontend", STRLENOF("frontend") ))
+ isfrontend = 1;
+ else if ( !strncmp( rdn.bv_val + rdn.bv_len - STRLENOF("config"),
+ "config", STRLENOF("config") ))
+ isconfig = 1;
+ }
ptr1 = ber_bvchr( &e->e_name, '{' );
if ( ptr1 && ptr1 - e->e_name.bv_val < rdn.bv_len ) {
char *next;
if ( index != -1 || !isfrontend )
return LDAP_NAMING_VIOLATION;
}
+ if ( isconfig && index != 0 ){
+ return LDAP_NAMING_VIOLATION;
+ }
}
/* count related kids */
if ( ce->ce_type == ce_type ) nsibs++;
}
+ /* account for -1 frontend */
+ if ( ce_type == Cft_Database )
+ nsibs--;
+
if ( index != nsibs ) {
if ( gotindex ) {
if ( index < nsibs ) {
renumber = 1;
}
}
- if ( !isfrontend && index == -1 )
+ /* config DB is always "0" */
+ if ( isconfig && index == -1 ) {
+ index = 0;
+ }
+ if ( !isfrontend && index == -1 ) {
index = nsibs;
+ }
/* just make index = nsibs */
if ( !renumber ) {
return rc;
}
+static int
+count_oc( ObjectClass *oc, ConfigOCs ***copp, int *nocs )
+{
+ ConfigOCs co, *cop;
+ ObjectClass **sups;
+
+ co.co_name = &oc->soc_cname;
+ cop = avl_find( CfOcTree, &co, CfOc_cmp );
+ if ( cop ) {
+ int i;
+
+ /* check for duplicates */
+ for ( i = 0; i < *nocs; i++ ) {
+ if ( *copp && (*copp)[i] == cop ) {
+ break;
+ }
+ }
+
+ if ( i == *nocs ) {
+ ConfigOCs **tmp = ch_realloc( *copp, (*nocs + 1)*sizeof( ConfigOCs * ) );
+ if ( tmp == NULL ) {
+ return -1;
+ }
+ *copp = tmp;
+ (*copp)[*nocs] = cop;
+ (*nocs)++;
+ }
+ }
+
+ for ( sups = oc->soc_sups; sups && *sups; sups++ ) {
+ if ( count_oc( *sups, copp, nocs ) ) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static ConfigOCs **
count_ocs( Attribute *oc_at, int *nocs )
{
- int i, j, n;
- ConfigOCs co, *coptr, **colst;
+ int i;
+ ConfigOCs **colst = NULL;
- /* count the objectclasses */
- for ( i=0; oc_at->a_nvals[i].bv_val; i++ );
- n = i;
- colst = (ConfigOCs **)ch_malloc( n * sizeof(ConfigOCs *));
+ *nocs = 0;
- for ( i=0, j=0; i<n; i++) {
- co.co_name = &oc_at->a_nvals[i];
- coptr = avl_find( CfOcTree, &co, CfOc_cmp );
-
- /* ignore non-config objectclasses. probably should be
- * an error, general data doesn't belong here.
- */
- if ( !coptr ) continue;
+ for ( i = 0; !BER_BVISNULL( &oc_at->a_nvals[i] ); i++ )
+ /* count attrs */ ;
- /* Ignore the root objectclass, it has no implementation.
- */
- if ( coptr->co_type == Cft_Abstract ) continue;
- colst[j++] = coptr;
+ for ( ; i--; ) {
+ ObjectClass *oc = oc_bvfind( &oc_at->a_nvals[i] );
+
+ assert( oc != NULL );
+ if ( count_oc( oc, &colst, nocs ) ) {
+ ch_free( colst );
+ return NULL;
+ }
}
- *nocs = j;
+
return colst;
}
static int
cfAddDatabase( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
{
- if ( p->ce_type != Cft_Global )
+ if ( p->ce_type != Cft_Global ) {
return LDAP_CONSTRAINT_VIOLATION;
+ }
ca->be = frontendDB; /* just to get past check_vals */
return LDAP_SUCCESS;
}
static int
cfAddBackend( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
{
- if ( p->ce_type != Cft_Global )
+ if ( p->ce_type != Cft_Global ) {
return LDAP_CONSTRAINT_VIOLATION;
+ }
return LDAP_SUCCESS;
}
static int
cfAddModule( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
{
- if ( p->ce_type != Cft_Global )
+ if ( p->ce_type != Cft_Global ) {
return LDAP_CONSTRAINT_VIOLATION;
+ }
return LDAP_SUCCESS;
}
static int
cfAddOverlay( CfEntryInfo *p, Entry *e, struct config_args_s *ca )
{
- if ( p->ce_type != Cft_Database )
+ if ( p->ce_type != Cft_Database ) {
return LDAP_CONSTRAINT_VIOLATION;
+ }
ca->be = p->ce_be;
return LDAP_SUCCESS;
}
struct berval bv = BER_BVC("olcDitContentRules");
ad = NULL;
slap_bv2ad( &bv, &ad, &text );
- ct = config_find_table( colst, nocs, ad );
+ ct = config_find_table( colst, nocs, ad, ca );
config_del_vals( ct, ca );
}
if ( cfn->c_oc_head ) {
struct berval bv = BER_BVC("olcObjectClasses");
ad = NULL;
slap_bv2ad( &bv, &ad, &text );
- ct = config_find_table( colst, nocs, ad );
+ ct = config_find_table( colst, nocs, ad, ca );
config_del_vals( ct, ca );
}
if ( cfn->c_at_head ) {
struct berval bv = BER_BVC("olcAttributeTypes");
ad = NULL;
slap_bv2ad( &bv, &ad, &text );
- ct = config_find_table( colst, nocs, ad );
+ ct = config_find_table( colst, nocs, ad, ca );
config_del_vals( ct, ca );
}
if ( cfn->c_om_head ) {
struct berval bv = BER_BVC("olcObjectIdentifier");
ad = NULL;
slap_bv2ad( &bv, &ad, &text );
- ct = config_find_table( colst, nocs, ad );
+ ct = config_find_table( colst, nocs, ad, ca );
config_del_vals( ct, ca );
}
cfo = p->ce_private;
ch_free( cfn );
}
+static int
+config_add_oc( ConfigOCs **cop, CfEntryInfo *last, Entry *e, ConfigArgs *ca )
+{
+ int rc = LDAP_CONSTRAINT_VIOLATION;
+ ObjectClass **ocp;
+
+ if ( (*cop)->co_ldadd ) {
+ rc = (*cop)->co_ldadd( last, e, ca );
+ if ( rc != LDAP_CONSTRAINT_VIOLATION ) {
+ return rc;
+ }
+ }
+
+ for ( ocp = (*cop)->co_oc->soc_sups; ocp && *ocp; ocp++ ) {
+ ConfigOCs co = { 0 };
+
+ co.co_name = &(*ocp)->soc_cname;
+ *cop = avl_find( CfOcTree, &co, CfOc_cmp );
+ if ( *cop == NULL ) {
+ return rc;
+ }
+
+ rc = config_add_oc( cop, last, e, ca );
+ if ( rc != LDAP_CONSTRAINT_VIOLATION ) {
+ return rc;
+ }
+ }
+
+ return rc;
+}
+
/* Parse an LDAP entry into config directives */
static int
config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
int *renum, Operation *op )
{
- CfEntryInfo *ce, *last;
- ConfigOCs **colst;
- Attribute *a, *oc_at;
- int i, ibase = -1, nocs, rc = 0;
- struct berval pdn;
- ConfigTable *ct;
- char *ptr;
+ CfEntryInfo *ce, *last = NULL;
+ ConfigOCs co, *coptr, **colst;
+ Attribute *a, *oc_at, *soc_at;
+ int i, ibase = -1, nocs, rc = 0;
+ struct berval pdn;
+ ConfigTable *ct;
+ char *ptr;
memset( ca, 0, sizeof(ConfigArgs));
*/
ce = config_find_base( cfb->cb_root, &e->e_nname, &last );
if ( ce ) {
- if (( op && op->o_managedsait ) ||
+ if ( ( op && op->o_managedsait ) ||
( ce->ce_type != Cft_Database && ce->ce_type != Cft_Overlay &&
- ce->ce_type != Cft_Module ))
- return LDAP_ALREADY_EXISTS;
+ ce->ce_type != Cft_Module ) )
+ {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" already exists\n",
+ op->o_log_prefix, e->e_name.bv_val, 0 );
+ return LDAP_ALREADY_EXISTS;
+ }
}
dnParent( &e->e_nname, &pdn );
/* If last is NULL, the new entry is the root/suffix entry,
* otherwise last should be the parent.
*/
- if ( last && !dn_match( &last->ce_entry->e_nname, &pdn )) {
- if ( rs )
+ if ( last && !dn_match( &last->ce_entry->e_nname, &pdn ) ) {
+ if ( rs ) {
rs->sr_matched = last->ce_entry->e_name.bv_val;
+ }
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" not child of DN=\"%s\"\n",
+ op ? op->o_log_prefix : "", e->e_name.bv_val,
+ last->ce_entry->e_name.bv_val );
return LDAP_NO_SUCH_OBJECT;
}
if ( op ) {
/* No parent, must be root. This will never happen... */
- if ( !last && !be_isroot( op ) && !be_shadow_update( op ))
+ if ( !last && !be_isroot( op ) && !be_shadow_update( op ) ) {
return LDAP_NO_SUCH_OBJECT;
+ }
+
if ( last && !access_allowed( op, last->ce_entry,
- slap_schema.si_ad_children, NULL, ACL_WADD, NULL ))
+ slap_schema.si_ad_children, NULL, ACL_WADD, NULL ) )
+ {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no write access to \"children\" of parent\n",
+ op->o_log_prefix, e->e_name.bv_val, 0 );
return LDAP_INSUFFICIENT_ACCESS;
+ }
}
oc_at = attr_find( e->e_attrs, slap_schema.si_ad_objectClass );
- if ( !oc_at ) return LDAP_OBJECT_CLASS_VIOLATION;
+ if ( !oc_at ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no objectClass\n",
+ op ? op->o_log_prefix : "", e->e_name.bv_val, 0 );
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
+
+ soc_at = attr_find( e->e_attrs, slap_schema.si_ad_structuralObjectClass );
+ if ( !soc_at ) {
+ ObjectClass *soc = NULL;
+ char textbuf[ SLAP_TEXT_BUFLEN ];
+ const char *text = textbuf;
+
+ /* FIXME: check result */
+ rc = structural_class( oc_at->a_nvals, &soc, NULL,
+ &text, textbuf, sizeof(textbuf), NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass (%s)\n",
+ op ? op->o_log_prefix : "", e->e_name.bv_val, text );
+ return rc;
+ }
+ attr_merge_one( e, slap_schema.si_ad_structuralObjectClass, &soc->soc_cname, NULL );
+ soc_at = attr_find( e->e_attrs, slap_schema.si_ad_structuralObjectClass );
+ if ( soc_at == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass; "
+ "unable to merge computed class %s\n",
+ op ? op->o_log_prefix : "", e->e_name.bv_val,
+ soc->soc_cname.bv_val );
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
+
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass; "
+ "computed objectClass %s merged\n",
+ op ? op->o_log_prefix : "", e->e_name.bv_val,
+ soc->soc_cname.bv_val );
+ }
/* Fake the coordinates based on whether we're part of an
* LDAP Add or if reading the config dir
}
ca->ca_op = op;
- colst = count_ocs( oc_at, &nocs );
+ co.co_name = &soc_at->a_nvals[0];
+ coptr = avl_find( CfOcTree, &co, CfOc_cmp );
+ if ( coptr == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass in configuration table\n",
+ op ? op->o_log_prefix : "", e->e_name.bv_val, 0 );
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
/* Only the root can be Cft_Global, everything else must
* have a parent. Only limited nesting arrangements are allowed.
*/
rc = LDAP_CONSTRAINT_VIOLATION;
- if ( colst[0]->co_type == Cft_Global && !last ) {
+ if ( coptr->co_type == Cft_Global && !last ) {
cfn = cfb->cb_config;
ca->private = cfn;
ca->be = frontendDB; /* just to get past check_vals */
* any necessary arg setup
*/
if ( last ) {
- for ( i=0; i<nocs; i++ ) {
- if ( colst[i]->co_ldadd &&
- ( rc = colst[i]->co_ldadd( last, e, ca ))
- != LDAP_CONSTRAINT_VIOLATION ) {
- break;
- }
+ rc = config_add_oc( &coptr, last, e, ca );
+ if ( rc == LDAP_CONSTRAINT_VIOLATION ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
+ "DN=\"%s\" no structural objectClass add function\n",
+ op ? op->o_log_prefix : "", e->e_name.bv_val, 0 );
+ return LDAP_OBJECT_CLASS_VIOLATION;
}
}
+ colst = count_ocs( oc_at, &nocs );
+
/* Add the entry but don't parse it, we already have its contents */
if ( rc == LDAP_COMPARE_TRUE ) {
rc = LDAP_SUCCESS;
* but only the other types support auto-renumbering of siblings.
*/
{
- rc = check_name_index( last, colst[0]->co_type, e, rs, renum,
+ rc = check_name_index( last, coptr->co_type, e, rs, renum,
&ibase );
if ( rc ) {
goto done_noop;
}
- if ( renum && *renum && colst[0]->co_type != Cft_Database &&
- colst[0]->co_type != Cft_Overlay ) {
+ if ( renum && *renum && coptr->co_type != Cft_Database &&
+ coptr->co_type != Cft_Overlay )
+ {
snprintf( ca->msg, sizeof( ca->msg ),
"operation requires sibling renumbering" );
rc = LDAP_UNWILLING_TO_PERFORM;
/* Make sure we process attrs in the required order */
sort_attrs( e, colst, nocs );
- for ( a=e->e_attrs; a; a=a->a_next ) {
+ for ( a = e->e_attrs; a; a = a->a_next ) {
if ( a == oc_at ) continue;
- ct = config_find_table( colst, nocs, a->a_desc );
+ ct = config_find_table( colst, nocs, a->a_desc, ca );
if ( !ct ) continue; /* user data? */
rc = check_vals( ct, ca, a, 1 );
if ( rc ) goto done_noop;
/* Basic syntax checks are OK. Do the actual settings. */
for ( a=e->e_attrs; a; a=a->a_next ) {
if ( a == oc_at ) continue;
- ct = config_find_table( colst, nocs, a->a_desc );
+ ct = config_find_table( colst, nocs, a->a_desc, ca );
if ( !ct ) continue; /* user data? */
for (i=0; a->a_vals[i].bv_val; i++) {
char *iptr = NULL;
strcpy( ca->log, "back-config" );
for (ml = op->orm_modlist; ml; ml=ml->sml_next) {
- ct = config_find_table( colst, nocs, ml->sml_desc );
+ ct = config_find_table( colst, nocs, ml->sml_desc, ca );
switch (ml->sml_op) {
case LDAP_MOD_DELETE:
case LDAP_MOD_REPLACE: {
}
/* Basic syntax checks are OK. Do the actual settings. */
for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
- ct = config_find_table( colst, nocs, ml->sml_desc );
+ ct = config_find_table( colst, nocs, ml->sml_desc, ca );
if ( !ct ) continue;
s = attr_find( save_attrs, ml->sml_desc );
ca->valx = d->idx[i];
rc = config_del_vals( ct, ca );
if ( rc != LDAP_SUCCESS ) break;
- s->a_flags |= SLAP_ATTR_IXDEL;
+ if ( s )
+ s->a_flags |= SLAP_ATTR_IXDEL;
for (j=i+1; j < d->nidx; j++)
if ( d->idx[j] >d->idx[i] )
d->idx[j]--;
ca->line = NULL;
rc = config_del_vals( ct, ca );
if ( rc ) rc = LDAP_OTHER;
- s->a_flags |= SLAP_ATTR_IXDEL;
+ if ( s )
+ s->a_flags |= SLAP_ATTR_IXDEL;
}
if ( ml->sml_values ) {
d = d->next;
for ( s = save_attrs; s; s = s->a_next ) {
if ( s->a_flags & SLAP_ATTR_IXDEL ) {
s->a_flags &= ~(SLAP_ATTR_IXDEL|SLAP_ATTR_IXADD);
- ct = config_find_table( colst, nocs, s->a_desc );
+ ct = config_find_table( colst, nocs, s->a_desc, ca );
a = attr_find( e->e_attrs, s->a_desc );
if ( a ) {
/* clear the flag so the add check below will skip it */
}
for ( a = e->e_attrs; a; a = a->a_next ) {
if ( a->a_flags & SLAP_ATTR_IXADD ) {
- ct = config_find_table( colst, nocs, a->a_desc );
+ ct = config_find_table( colst, nocs, a->a_desc, ca );
ca->valx = -1;
ca->line = NULL;
config_del_vals( ct, ca );
Entry *e,
int rw )
{
+ if ( !e->e_private ) {
+ entry_free( e );
+ }
return LDAP_SUCCESS;
}
ce->ce_parent = parent;
if ( parent ) {
pdn = parent->ce_entry->e_nname;
- if ( parent->ce_kids && parent->ce_kids->ce_type < ce->ce_type )
+ if ( parent->ce_kids )
for ( ceprev = parent->ce_kids; ceprev->ce_sibs &&
- ceprev->ce_type < ce->ce_type;
+ ceprev->ce_type <= ce->ce_type;
ceprev = ceprev->ce_sibs );
} else {
BER_BVZERO( &pdn );
attr_merge_normalize_one(e, ad, &val, NULL );
oc = main->co_oc;
+ c->table = main->co_type;
if ( oc->soc_required )
config_build_attrs( e, oc->soc_required, ad, main->co_table, c );
if ( extra ) {
oc = extra->co_oc;
+ c->table = extra->co_type;
if ( oc->soc_required )
config_build_attrs( e, oc->soc_required, ad, extra->co_table, c );
struct berval bv;
for (; cf; cf=cf->c_sibs, c->depth++) {
+ if ( !cf->c_at_head && !cf->c_cr_head && !cf->c_oc_head &&
+ !cf->c_om_head ) continue;
c->value_dn.bv_val = c->log;
+ LUTIL_SLASHPATH( cf->c_file.bv_val );
bv.bv_val = strrchr(cf->c_file.bv_val, LDAP_DIRSEP[0]);
if ( !bv.bv_val ) {
bv = cf->c_file;
return NULL;
}
+static int entry_put_got_frontend=0;
+static int entry_put_got_config=0;
static ID
config_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
{
CfBackInfo *cfb = be->be_private;
BackendInfo *bi = cfb->cb_db.bd_info;
+ int rc;
+ struct berval rdn, vals[ 2 ];
ConfigArgs ca;
+ OperationBuffer opbuf;
+ Entry *ce;
+ Attribute *attr;
+ Connection conn = {0};
+ Operation *op = NULL;
+ SlapReply rs = {REP_RESULT};
+ void *thrctx;
+ /* Create entry for frontend database if it does not exist already */
+ if ( !entry_put_got_frontend ) {
+ if ( !strncmp( e->e_nname.bv_val, "olcDatabase",
+ STRLENOF( "olcDatabase" ))) {
+ if ( strncmp( e->e_nname.bv_val +
+ STRLENOF( "olcDatabase" ), "={-1}frontend",
+ STRLENOF( "={-1}frontend" )) &&
+ strncmp( e->e_nname.bv_val +
+ STRLENOF( "olcDatabase" ), "=frontend",
+ STRLENOF( "=frontend" ))) {
+ vals[1].bv_len = 0;
+ vals[1].bv_val = NULL;
+ memset( &ca, 0, sizeof(ConfigArgs));
+ ca.be = frontendDB;
+ ca.bi = frontendDB->bd_info;
+ ca.be->be_cf_ocs = &CFOC_FRONTEND;
+ rdn.bv_val = ca.log;
+ rdn.bv_len = snprintf(rdn.bv_val, sizeof( ca.log ),
+ "%s=" SLAP_X_ORDERED_FMT "%s",
+ cfAd_database->ad_cname.bv_val, -1,
+ ca.bi->bi_type);
+ ce = config_build_entry( NULL, NULL, cfb->cb_root, &ca, &rdn,
+ &CFOC_DATABASE, ca.be->be_cf_ocs );
+ op = (Operation *) &opbuf;
+ thrctx = ldap_pvt_thread_pool_context();
+ connection_fake_init2( &conn, op, thrctx,0 );
+ op->o_bd = &cfb->cb_db;
+ op->o_tag = LDAP_REQ_ADD;
+ op->ora_e = ce;
+ op->o_dn = be->be_rootdn;
+ op->o_ndn = be->be_rootndn;
+ rc = slap_add_opattrs(op, NULL, NULL, 0, 0);
+ if ( rc != LDAP_SUCCESS ) {
+ text->bv_val = "autocreation of \"olcDatabase={-1}frontend\" failed";
+ text->bv_len = STRLENOF("autocreation of \"olcDatabase={-1}frontend\" failed");
+ return NOID;
+ }
+
+ if ( ce && bi && bi->bi_tool_entry_put &&
+ bi->bi_tool_entry_put( &cfb->cb_db, ce, text ) != NOID ) {
+ entry_put_got_frontend++;
+ } else {
+ text->bv_val = "autocreation of \"olcDatabase={-1}frontend\" failed";
+ text->bv_len = STRLENOF("autocreation of \"olcDatabase={-1}frontend\" failed");
+ return NOID;
+ }
+ } else {
+ entry_put_got_frontend++;
+ }
+ }
+ }
+ /* Create entry for config database if it does not exist already */
+ if ( !entry_put_got_config ) {
+ if ( !strncmp( e->e_nname.bv_val, "olcDatabase",
+ STRLENOF( "olcDatabase" ))) {
+ if ( strncmp( e->e_nname.bv_val +
+ STRLENOF( "olcDatabase" ), "={0}config",
+ STRLENOF( "={0}config" )) &&
+ strncmp( e->e_nname.bv_val +
+ STRLENOF( "olcDatabase" ), "=config",
+ STRLENOF( "=config" )) ) {
+ vals[1].bv_len = 0;
+ vals[1].bv_val = NULL;
+ memset( &ca, 0, sizeof(ConfigArgs));
+ ca.be = LDAP_STAILQ_FIRST( &backendDB );
+ ca.bi = ca.be->bd_info;
+ rdn.bv_val = ca.log;
+ rdn.bv_len = snprintf(rdn.bv_val, sizeof( ca.log ),
+ "%s=" SLAP_X_ORDERED_FMT "%s",
+ cfAd_database->ad_cname.bv_val, 0,
+ ca.bi->bi_type);
+ ce = config_build_entry( NULL, NULL, cfb->cb_root, &ca, &rdn, &CFOC_DATABASE,
+ ca.be->be_cf_ocs );
+ if ( ! op ) {
+ thrctx = ldap_pvt_thread_pool_context();
+ op = (Operation *) &opbuf;
+ connection_fake_init2( &conn, op, thrctx,0 );
+ op->o_bd = &cfb->cb_db;
+ op->o_tag = LDAP_REQ_ADD;
+ op->o_dn = be->be_rootdn;
+ op->o_ndn = be->be_rootndn;
+ }
+ op->ora_e = ce;
+ rc = slap_add_opattrs(op, NULL, NULL, 0, 0);
+ if ( rc != LDAP_SUCCESS ) {
+ text->bv_val = "autocreation of \"olcDatabase={0}config\" failed";
+ text->bv_len = STRLENOF("autocreation of \"olcDatabase={0}config\" failed");
+ return NOID;
+ }
+ if (ce && bi && bi->bi_tool_entry_put &&
+ bi->bi_tool_entry_put( &cfb->cb_db, ce, text ) != NOID ) {
+ entry_put_got_config++;
+ } else {
+ text->bv_val = "autocreation of \"olcDatabase={0}config\" failed";
+ text->bv_len = STRLENOF("autocreation of \"olcDatabase={0}config\" failed");
+ return NOID;
+ }
+ } else {
+ entry_put_got_config++;
+ }
+ }
+ }
if ( bi && bi->bi_tool_entry_put &&
config_add_internal( cfb, e, &ca, NULL, NULL, NULL ) == 0 )
return bi->bi_tool_entry_put( &cfb->cb_db, e, text );