ando@sys-net.it wrote:
The above had nothing to do with your problem. Your problem is related to the fact that you intermixed overlay and database configuration statements, so the idletimeout statement after the accesslog overlay instantiation was causing invalid memory write (beyond the private data of the accesslog overlay instead of in the private data of the bdb database) resulting in heap corruption.
Maybe it hasn't been stressed enough, but the order of directives is:
I believe the problem is here:
========================================================================= diff -u -r1.341.2.25 config.c --- servers/slapd/config.c 8 Feb 2007 12:31:24 -0000 1.341.2.25 +++ servers/slapd/config.c 24 Feb 2007 13:29:42 -0000 @@ -308,13 +308,28 @@ return(0); } if(arg_type & ARG_OFFSET) { - if (c->be && (!overlay_is_over(c->be) || - ((slap_overinfo *)c->be->bd_info)->oi_orig == c->bi)) - ptr = c->be->be_private; - else if (c->bi) + if ( c->be ) { + if (!overlay_is_over(c->be) || + ((slap_overinfo *)c->be->bd_info)->oi_orig == c->bi) + { + ptr = c->be->be_private; + + } else { + snprintf( c->msg, sizeof( c->msg ), + "<%s> statement outside scope " + "(after overlay?)", + c->argv[0] ); + Debug(LDAP_DEBUG_CONFIG, "%s: %s!\n", + c->log, c->msg, 0); + return(ARG_BAD_CONF); + } + + } else if ( c->bi ) { ptr = c->bi->bi_private; - else { - snprintf( c->msg, sizeof( c->msg ), "<%s> offset is missing base pointer", + + } else { + snprintf( c->msg, sizeof( c->msg ), + "<%s> offset is missing base pointer", c->argv[0] ); Debug(LDAP_DEBUG_CONFIG, "%s: %s!\n", c->log, c->msg, 0); =========================================================================
that is, if both the database and the overlay allow back-config, there are cases in which config_set_vals() can be called with (arg_type & ARG_OFFSET) and the c->be points to the database's structure while c->bi points to the overlay's structure, and the config statement refers to the database although appearing after the overlay's instantiation.
This is Bad (TM) and should be avoided. However, for example, I have special needs in back-meta that require to allow overlay instantiation __before__ the database configuration is complete (in that case, I need an overlay to be instantiated before targets are defined, so that the overlay can get per-target configuration parameters much like the underlying database does). This may defer introduction of back-config support for back-meta.
Comments?
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.n.c. Via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ------------------------------------------ Office: +39.02.23998309 Mobile: +39.333.4963172 Email: pierangelo.masarati@sys-net.it ------------------------------------------
Pierangelo Masarati wrote:
that is, if both the database and the overlay allow back-config, there are cases in which config_set_vals() can be called with (arg_type & ARG_OFFSET) and the c->be points to the database's structure while c->bi points to the overlay's structure, and the config statement refers to the database although appearing after the overlay's instantiation.
This is Bad (TM) and should be avoided. However, for example, I have special needs in back-meta that require to allow overlay instantiation __before__ the database configuration is complete (in that case, I need an overlay to be instantiated before targets are defined, so that the overlay can get per-target configuration parameters much like the underlying database does). This may defer introduction of back-config support for back-meta.
Please disregard the above patch, which is incorrect as well. I think the right way to address the problem of selecting the right context for configure statements definitely consists in attaching into the ConfigTable a Conf->bi pointer to the BackendInfo that ConfigTable entry belongs to. This would allow to determine if the ConfigTable entry belongs to the underlying database, to an overlay, to the frontend or whatever, by comparing the BackendInfo* with that of the above stuff. Something like:
if ( c->be ) { if ( !overlay_is_over( c->be ) ) { ptr = c->be->be_private; } else if (((slap_overinfo *)c->be->bd_info)->oi_orig == Conf->bi ) { ptr = c->be->be_private; } }
if ( ptr == NULL && c->bi && c->bi->bi_type == Conf->bi->bi_type ) { ptr = c->bi->bi_private; } else { // error }
or whatever.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.n.c. Via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ------------------------------------------ Office: +39.02.23998309 Mobile: +39.333.4963172 Email: pierangelo.masarati@sys-net.it ------------------------------------------
Pierangelo Masarati wrote:
Please disregard the above patch, which is incorrect as well. I think the right way to address the problem of selecting the right context for configure statements definitely consists in attaching into the ConfigTable a Conf->bi pointer to the BackendInfo that ConfigTable entry belongs to. This would allow to determine if the ConfigTable entry belongs to the underlying database, to an overlay, to the frontend or whatever, by comparing the BackendInfo* with that of the above stuff.
Agreed. The actual pointer is not needed, just an enum to indicate which to use. I can work that up.
Something like:
if ( c->be ) { if ( !overlay_is_over( c->be ) ) { ptr = c->be->be_private; } else if (((slap_overinfo *)c->be->bd_info)->oi_orig == Conf->bi ) { ptr = c->be->be_private; } }
if ( ptr == NULL && c->bi && c->bi->bi_type == Conf->bi->bi_type ) { ptr = c->bi->bi_private; } else { // error }
or whatever.
Howard Chu wrote:
Agreed. The actual pointer is not needed, just an enum to indicate which to use. I can work that up.
OK. In fact, adding a pointer, although maybe more flexible, was getting a real mess since back-config stuff is now everywhere :)
Thanks, p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.n.c. Via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ------------------------------------------ Office: +39.02.23998309 Mobile: +39.333.4963172 Email: pierangelo.masarati@sys-net.it ------------------------------------------