Commit 61ee5897 authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

various improvements

parent d28cf4a7
......@@ -61,15 +61,16 @@ struct berval lastmodType[] = {
};
static struct m_s {
char *name;
char *schema;
slap_mask_t flags;
int offset;
char *name;
char *schema;
slap_mask_t flags;
int offset;
} moc[] = {
{ "lastmod", "( 1.3.6.1.4.1.4203.666.3.13"
"NAME 'lastmod' "
"DESC 'OpenLDAP per-database last modification monitoring' "
"SUP top STRUCTURAL "
"STRUCTURAL "
"SUP top "
"MUST cn "
"MAY ( "
"lastmodDN "
......@@ -96,7 +97,7 @@ static struct m_s {
"SINGLE-VALUE "
"NO-USER-MODIFICATION "
"USAGE directoryOperation )", SLAP_AT_HIDE,
offsetof(struct lastmod_schema_t, lms_ad_lastmodType) },
offsetof( struct lastmod_schema_t, lms_ad_lastmodType ) },
{ NULL }
};
......@@ -108,22 +109,26 @@ static const struct berval *write_exop[] = {
static int
lastmod_search( Operation *op, SlapReply *rs )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private;
int rc;
/* if we get here, it must be a success */
rs->sr_err = LDAP_SUCCESS;
#if 0
/* FIXME: can't restore the correct bd_info otherwise
* backend_operational() screws things up */
op->o_bd->bd_info = (BackendInfo *)on->on_info;
#endif
ldap_pvt_thread_mutex_lock( &lmi->lmi_entry_mutex );
rs->sr_attrs = op->ors_attrs;
rs->sr_flags = 0;
rs->sr_entry = lmi->lmi_e;
rs->sr_err = send_search_entry( op, rs );
rs->sr_entry = NULL;
rs->sr_flags = 0;
rs->sr_attrs = NULL;
rc = test_filter( op, lmi->lmi_e, op->oq_search.rs_filter );
if ( rc == LDAP_COMPARE_TRUE ) {
rs->sr_attrs = op->ors_attrs;
rs->sr_flags = 0;
rs->sr_entry = lmi->lmi_e;
rs->sr_err = send_search_entry( op, rs );
rs->sr_entry = NULL;
rs->sr_flags = 0;
rs->sr_attrs = NULL;
}
ldap_pvt_thread_mutex_unlock( &lmi->lmi_entry_mutex );
send_ldap_result( op, rs );
......@@ -134,13 +139,14 @@ lastmod_search( Operation *op, SlapReply *rs )
static int
lastmod_compare( Operation *op, SlapReply *rs )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private;
Attribute *a;
ldap_pvt_thread_mutex_lock( &lmi->lmi_entry_mutex );
if ( get_assert( op ) &&
( test_filter( op, lmi->lmi_e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
( test_filter( op, lmi->lmi_e, get_assertion( op ) ) != LDAP_COMPARE_TRUE ) )
{
rs->sr_err = LDAP_ASSERTION_FAILED;
goto return_results;
......@@ -157,7 +163,7 @@ lastmod_compare( Operation *op, SlapReply *rs )
for ( a = attr_find( lmi->lmi_e->e_attrs, op->oq_compare.rs_ava->aa_desc );
a != NULL;
a = attr_find( a->a_next, op->oq_compare.rs_ava->aa_desc ))
a = attr_find( a->a_next, op->oq_compare.rs_ava->aa_desc ) )
{
rs->sr_err = LDAP_COMPARE_FALSE;
......@@ -172,7 +178,9 @@ lastmod_compare( Operation *op, SlapReply *rs )
}
return_results:;
ldap_pvt_thread_mutex_unlock( &lmi->lmi_entry_mutex );
send_ldap_result( op, rs );
if( rs->sr_err == LDAP_COMPARE_FALSE || rs->sr_err == LDAP_COMPARE_TRUE ) {
......@@ -185,7 +193,7 @@ return_results:;
static int
lastmod_exop( Operation *op, SlapReply *rs )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
/* Temporary */
......@@ -201,7 +209,7 @@ lastmod_exop( Operation *op, SlapReply *rs )
static int
lastmod_op_func( Operation *op, SlapReply *rs )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private;
unsigned i;
......@@ -246,12 +254,15 @@ return_referral:;
rs->sr_ref = referral_rewrite( default_referral,
NULL, &op->o_req_dn, op->ors_scope );
if (!rs->sr_ref) rs->sr_ref = default_referral;
if ( !rs->sr_ref ) {
rs->sr_ref = default_referral;
}
rs->sr_err = LDAP_REFERRAL;
send_ldap_result( op, rs );
if (rs->sr_ref != default_referral)
ber_bvarray_free( rs->sr_ref );
if ( rs->sr_ref != default_referral ) {
ber_bvarray_free( rs->sr_ref );
}
rs->sr_ref = NULL;
return -1;
......@@ -264,10 +275,50 @@ return_error:;
return -1;
}
static int
best_guess( Operation *op,
struct berval *bv_modifyTimestamp, struct berval *bv_nmodifyTimestamp,
struct berval *bv_modifiersName, struct berval *bv_nmodifiersName )
{
struct tm *tm;
#ifdef HAVE_GMTIME_R
struct tm tm_buf;
#endif
char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
time_t currtime;
/* best guess */
#if 0
currtime = slap_get_time();
#endif
/* maybe we better use the time the operation was initiated */
currtime = op->o_time;
#ifndef HAVE_GMTIME_R
ldap_pvt_thread_mutex_lock( &gmtime_mutex );
tm = gmtime( &currtime );
#else /* HAVE_GMTIME_R */
tm = gmtime_r( &currtime, &tm_buf );
#endif /* HAVE_GMTIME_R */
lutil_gentime( tmbuf, sizeof( tmbuf ), tm );
#ifndef HAVE_GMTIME_R
ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
#endif
ber_str2bv( tmbuf, 0, 1, bv_modifyTimestamp );
ber_dupbv( bv_nmodifyTimestamp, bv_modifyTimestamp );
/* best guess */
ber_dupbv( bv_modifiersName, &op->o_dn );
ber_dupbv( bv_nmodifiersName, &op->o_ndn );
return 0;
}
static int
lastmod_update( Operation *op, SlapReply *rs )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private;
Attribute *a;
Modifications *ml = NULL;
......@@ -305,41 +356,26 @@ lastmod_update( Operation *op, SlapReply *rs )
break;
case LDAP_REQ_DELETE:
{
struct tm *tm;
#ifdef HAVE_GMTIME_R
struct tm tm_buf;
#endif
char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
time_t currtime;
lmt = LASTMOD_DELETE;
/* best guess */
currtime = slap_get_time();
best_guess( op, &bv_modifyTimestamp, &bv_nmodifyTimestamp,
&bv_modifiersName, &bv_nmodifiersName );
#ifndef HAVE_GMTIME_R
ldap_pvt_thread_mutex_lock( &gmtime_mutex );
tm = gmtime( &currtime );
#else /* HAVE_GMTIME_R */
tm = gmtime_r( &currtime, &tm_buf );
#endif /* HAVE_GMTIME_R */
lutil_gentime( tmbuf, sizeof( tmbuf ), tm );
#ifndef HAVE_GMTIME_R
ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
#endif
ber_dupbv( &bv_name, &op->o_req_dn );
ber_dupbv( &bv_nname, &op->o_req_ndn );
break;
ber_str2bv( tmbuf, 0, 1, &bv_modifyTimestamp );
ber_dupbv( &bv_nmodifyTimestamp, &bv_modifyTimestamp );
case LDAP_REQ_EXTENDED:
lmt = LASTMOD_EXOP;
/* best guess */
ber_dupbv( &bv_modifiersName, &op->o_dn );
ber_dupbv( &bv_nmodifiersName, &op->o_ndn );
/* actually, password change is wrapped around a backend
* call to modify, so it never shows up as an exop... */
best_guess( op, &bv_modifyTimestamp, &bv_nmodifyTimestamp,
&bv_modifiersName, &bv_nmodifiersName );
ber_dupbv( &bv_name, &op->o_req_dn );
ber_dupbv( &bv_nname, &op->o_req_ndn );
break;
}
case LDAP_REQ_MODIFY:
lmt = LASTMOD_MODIFY;
......@@ -374,22 +410,28 @@ lastmod_update( Operation *op, SlapReply *rs )
case LDAP_REQ_MODRDN:
lmt = LASTMOD_MODRDN;
e = NULL;
if ( on->on_info->oi_orig->bi_entry_get_rw ) {
BackendInfo *bi = op->o_bd->bd_info;
struct berval dn = BER_BVNULL;
if ( op->orr_nnewSup && !BER_BVISNULL( op->orr_nnewSup ) ) {
build_new_dn( &dn, op->orr_nnewSup, &op->orr_nnewrdn, NULL );
if ( op->orr_newSup && !BER_BVISNULL( op->orr_newSup ) ) {
build_new_dn( &bv_name, op->orr_newSup, &op->orr_newrdn, NULL );
build_new_dn( &bv_nname, op->orr_nnewSup, &op->orr_nnewrdn, NULL );
} else {
struct berval pdn;
} else {
struct berval pdn;
dnParent( &op->o_req_ndn, &pdn );
build_new_dn( &dn, &pdn, &op->orr_nnewrdn, NULL );
}
dnParent( &op->o_req_dn, &pdn );
build_new_dn( &bv_name, &pdn, &op->orr_newrdn, NULL );
dnParent( &op->o_req_ndn, &pdn );
build_new_dn( &bv_nname, &pdn, &op->orr_nnewrdn, NULL );
}
if ( on->on_info->oi_orig->bi_entry_get_rw ) {
BackendInfo *bi = op->o_bd->bd_info;
int rc;
op->o_bd->bd_info = (BackendInfo *)on->on_info->oi_orig;
if ( (*op->o_bd->bd_info->bi_entry_get_rw)( op, &dn, NULL, NULL, 0, &e ) == LDAP_SUCCESS ) {
rc = (*op->o_bd->bd_info->bi_entry_get_rw)( op, &bv_name, NULL, NULL, 0, &e );
if ( rc == LDAP_SUCCESS ) {
a = attr_find( e->e_attrs, slap_schema.si_ad_modifiersName );
if ( a != NULL ) {
ber_dupbv( &bv_modifiersName, &a->a_vals[0] );
......@@ -405,15 +447,22 @@ lastmod_update( Operation *op, SlapReply *rs )
}
}
ber_dupbv( &bv_name, &e->e_name );
ber_dupbv( &bv_nname, &e->e_nname );
assert( dn_match( &bv_name, &e->e_name ) );
assert( dn_match( &bv_nname, &e->e_nname ) );
(*op->o_bd->bd_info->bi_entry_release_rw)( op, e, 0 );
}
ch_free( dn.bv_val );
op->o_bd->bd_info = bi;
}
/* if !bi_entry_get_rw || bi_entry_get_rw failed for any reason... */
if ( e == NULL ) {
best_guess( op, &bv_modifyTimestamp, &bv_nmodifyTimestamp,
&bv_modifiersName, &bv_nmodifiersName );
}
break;
default:
......@@ -446,7 +495,7 @@ lastmod_update( Operation *op, SlapReply *rs )
ch_free( a->a_vals[0].bv_val );
ber_dupbv( &a->a_vals[0], &lastmodType[ lmt ] );
ch_free( a->a_nvals[0].bv_val );
ber_dupbv( &a->a_vals[0], &lastmodType[ lmt ] );
ber_dupbv( &a->a_nvals[0], &lastmodType[ lmt ] );
#if 0
fprintf( stderr, "### modifiersName: %s %s\n", bv_modifiersName.bv_val, bv_nmodifiersName.bv_val );
......@@ -487,16 +536,22 @@ lastmod_response( Operation *op, SlapReply *rs )
{
unsigned int i;
if ( rs->sr_err != LDAP_SUCCESS ) {
/* don't record failed operations */
switch ( rs->sr_err ) {
case LDAP_SUCCESS:
/* FIXME: other cases? */
break;
default:
return SLAP_CB_CONTINUE;
}
/* record only write operations */
switch ( op->o_tag ) {
case LDAP_REQ_ADD:
case LDAP_REQ_MODIFY:
case LDAP_REQ_MODRDN:
case LDAP_REQ_DELETE:
/* FIXME: exop? */
break;
case LDAP_REQ_EXTENDED:
......@@ -513,10 +568,7 @@ lastmod_response( Operation *op, SlapReply *rs )
}
process:;
if ( rs->sr_err == LDAP_SUCCESS ) {
/* FIXME: ignore errors */
(void)lastmod_update( op, rs );
}
(void)lastmod_update( op, rs );
return SLAP_CB_CONTINUE;
}
......@@ -526,12 +578,12 @@ lastmod_db_init(
BackendDB *be
)
{
slap_overinst *on = (slap_overinst *) be->bd_info;
slap_overinst *on = (slap_overinst *)be->bd_info;
lastmod_info_t *lmi;
if ( lastmod_schema.lms_oc_lastmod == NULL ) {
int i;
const char *text;
int i;
const char *text;
/* schema integration */
for ( i = 0; mat[i].name; i++ ) {
......@@ -671,8 +723,8 @@ lastmod_db_init(
}
}
lmi = (lastmod_info_t *)ch_malloc(sizeof(lastmod_info_t));
memset(lmi, 0, sizeof(lastmod_info_t));
lmi = (lastmod_info_t *)ch_malloc( sizeof( lastmod_info_t ) );
memset( lmi, 0, sizeof( lastmod_info_t ) );
on->on_bi.bi_private = lmi;
return 0;
......@@ -680,14 +732,14 @@ lastmod_db_init(
static int
lastmod_db_config(
BackendDB *be,
const char *fname,
int lineno,
int argc,
char **argv
BackendDB *be,
const char *fname,
int lineno,
int argc,
char **argv
)
{
slap_overinst *on = (slap_overinst *) be->bd_info;
slap_overinst *on = (slap_overinst *)be->bd_info;
lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private;
if ( strcasecmp( argv[ 0 ], "lastmod-rdnvalue" ) == 0 ) {
......@@ -755,11 +807,11 @@ lastmod_db_open(
"modifyTimestamp: %s\n"
"modifiersName: %s\n"
"hasSubordinates: FALSE\n",
lmi->lmi_rdnvalue.bv_val, be->be_suffix[0].bv_val,
lmi->lmi_rdnvalue.bv_val, be->be_suffix[ 0 ].bv_val,
lastmod_schema.lms_oc_lastmod->soc_cname.bv_val,
lastmod_schema.lms_oc_lastmod->soc_cname.bv_val,
lmi->lmi_rdnvalue.bv_val,
lastmod_schema.lms_ad_lastmodDN->ad_cname.bv_val, lmi->lmi_rdnvalue.bv_val, be->be_suffix[0].bv_val,
lastmod_schema.lms_ad_lastmodDN->ad_cname.bv_val, lmi->lmi_rdnvalue.bv_val, be->be_suffix[ 0 ].bv_val,
lastmod_schema.lms_ad_lastmodType->ad_cname.bv_val, lastmodType[ LASTMOD_ADD ].bv_val,
tmbuf,
BER_BVISNULL( &be->be_rootdn ) ? "" : be->be_rootdn.bv_val,
......@@ -768,7 +820,6 @@ lastmod_db_open(
#if 0
fprintf( stderr, "# entry:\n%s\n", buf );
fflush( stderr );
#endif
lmi->lmi_e = str2entry( buf );
......@@ -786,7 +837,7 @@ lastmod_db_destroy(
BackendDB *be
)
{
slap_overinst *on = (slap_overinst *) be->bd_info;
slap_overinst *on = (slap_overinst *)be->bd_info;
lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private;
if ( lmi ) {
......@@ -838,7 +889,7 @@ lastmod_init()
#if SLAPD_OVER_LASTMOD == SLAPD_MOD_DYNAMIC
int
init_module(int argc, char *argv[])
init_module( int argc, char *argv[] )
{
return lastmod_init();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment