mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-07 23:51:21 -05:00
various improvements
This commit is contained in:
parent
d28cf4a77a
commit
61ee5897e0
1 changed files with 146 additions and 95 deletions
|
|
@ -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();
|
||||
|
||||
#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 );
|
||||
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_EXTENDED:
|
||||
lmt = LASTMOD_EXOP;
|
||||
|
||||
/* 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 ( 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;
|
||||
|
||||
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;
|
||||
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 );
|
||||
|
||||
} else {
|
||||
struct berval pdn;
|
||||
|
||||
dnParent( &op->o_req_ndn, &pdn );
|
||||
build_new_dn( &dn, &pdn, &op->orr_nnewrdn, NULL );
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue