mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-24 13:24:56 +08:00
Implement reqOld support
This commit is contained in:
parent
95f90b5759
commit
4f1e154c12
@ -57,6 +57,8 @@ typedef struct log_info {
|
||||
int li_age;
|
||||
int li_cycle;
|
||||
struct re_s *li_task;
|
||||
Filter *li_filter;
|
||||
Entry *li_old;
|
||||
int li_success;
|
||||
ldap_pvt_thread_mutex_t li_op_mutex;
|
||||
ldap_pvt_thread_mutex_t li_log_mutex;
|
||||
@ -68,7 +70,8 @@ enum {
|
||||
LOG_DB = 1,
|
||||
LOG_OPS,
|
||||
LOG_PURGE,
|
||||
LOG_SUCCESS
|
||||
LOG_SUCCESS,
|
||||
LOG_FILTER
|
||||
};
|
||||
|
||||
static ConfigTable log_cfats[] = {
|
||||
@ -90,6 +93,10 @@ static ConfigTable log_cfats[] = {
|
||||
log_cf_gen, "( OLcfgOvAt:4.4 NAME 'olcAccessLogSuccess' "
|
||||
"DESC 'Log successful ops only' "
|
||||
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
|
||||
{ "logoldfilter", NULL, 2, 2, 0, ARG_MAGIC|LOG_FILTER,
|
||||
log_cf_gen, "( OLcfgOvAt:4.5 NAME 'olcAccessLogOldFilter' "
|
||||
"DESC 'Log old values when modifying entries matching the filter' "
|
||||
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -99,7 +106,8 @@ static ConfigOCs log_cfocs[] = {
|
||||
"DESC 'Access log configuration' "
|
||||
"SUP olcOverlayConfig "
|
||||
"MUST olcAccessLogDB "
|
||||
"MAY ( olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogSuccess ) )",
|
||||
"MAY ( olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogSuccess $ "
|
||||
"olcAccessLogOldFilter ) )",
|
||||
Cft_Overlay, log_cfats },
|
||||
{ NULL }
|
||||
};
|
||||
@ -605,6 +613,14 @@ log_cf_gen(ConfigArgs *c)
|
||||
else
|
||||
rc = 1;
|
||||
break;
|
||||
case LOG_FILTER:
|
||||
if ( li->li_filter ) {
|
||||
filter2bv( li->li_filter, &agebv );
|
||||
value_add_one( &c->rvalue_vals, &agebv );
|
||||
}
|
||||
else
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LDAP_MOD_DELETE:
|
||||
@ -635,6 +651,12 @@ log_cf_gen(ConfigArgs *c)
|
||||
case LOG_SUCCESS:
|
||||
li->li_success = 0;
|
||||
break;
|
||||
case LOG_FILTER:
|
||||
if ( li->li_filter ) {
|
||||
filter_free( li->li_filter );
|
||||
li->li_filter = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -680,6 +702,12 @@ log_cf_gen(ConfigArgs *c)
|
||||
case LOG_SUCCESS:
|
||||
li->li_success = c->value_int;
|
||||
break;
|
||||
case LOG_FILTER:
|
||||
li->li_filter = str2filter( c->argv[1] );
|
||||
if ( !li->li_filter ) {
|
||||
sprintf( c->msg, "bad filter!" );
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -782,6 +810,24 @@ static struct berval derefs[] = {
|
||||
|
||||
static struct berval simple = BER_BVC("SIMPLE");
|
||||
|
||||
static void accesslog_val2val(AttributeDescription *ad, struct berval *val,
|
||||
char c_op, struct berval *dst) {
|
||||
char *ptr;
|
||||
|
||||
dst->bv_len = ad->ad_cname.bv_len + val->bv_len + 2;
|
||||
if ( c_op ) dst->bv_len++;
|
||||
|
||||
dst->bv_val = ch_malloc( dst->bv_len+1 );
|
||||
|
||||
ptr = lutil_strcopy( dst->bv_val, ad->ad_cname.bv_val );
|
||||
*ptr++ = ':';
|
||||
if ( c_op )
|
||||
*ptr++ = c_op;
|
||||
*ptr++ = ' ';
|
||||
AC_MEMCPY( ptr, val->bv_val, val->bv_len );
|
||||
dst->bv_val[dst->bv_len] = '\0';
|
||||
}
|
||||
|
||||
static int accesslog_response(Operation *op, SlapReply *rs) {
|
||||
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
|
||||
log_info *li = on->on_bi.bi_private;
|
||||
@ -791,7 +837,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
|
||||
int i;
|
||||
int logop;
|
||||
slap_verbmasks *lo;
|
||||
Entry *e;
|
||||
Entry *e, *old = NULL;
|
||||
char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE+8];
|
||||
struct berval bv;
|
||||
char *ptr;
|
||||
@ -821,6 +867,8 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
|
||||
|
||||
if ( lo->mask & LOG_OP_WRITES ) {
|
||||
ldap_pvt_thread_mutex_lock( &li->li_log_mutex );
|
||||
old = li->li_old;
|
||||
li->li_old = NULL;
|
||||
ldap_pvt_thread_mutex_unlock( &li->li_op_mutex );
|
||||
}
|
||||
|
||||
@ -844,9 +892,22 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
|
||||
|
||||
switch( logop ) {
|
||||
case LOG_EN_ADD:
|
||||
case LOG_EN_DELETE: {
|
||||
char c_op;
|
||||
Entry *e2;
|
||||
|
||||
if ( logop == LOG_EN_ADD ) {
|
||||
e2 = op->ora_e;
|
||||
c_op = '+';
|
||||
} else {
|
||||
if ( !old )
|
||||
break;
|
||||
e2 = old;
|
||||
c_op = 0;
|
||||
}
|
||||
/* count all the vals */
|
||||
i = 0;
|
||||
for ( a=op->ora_e->e_attrs; a; a=a->a_next ) {
|
||||
for ( a=e2->e_attrs; a; a=a->a_next ) {
|
||||
if ( a->a_vals ) {
|
||||
for (b=a->a_vals; !BER_BVISNULL( b ); b++) {
|
||||
i++;
|
||||
@ -855,32 +916,21 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
|
||||
}
|
||||
vals = ch_malloc( (i+1) * sizeof( struct berval ));
|
||||
i = 0;
|
||||
for ( a=op->ora_e->e_attrs; a; a=a->a_next ) {
|
||||
for ( a=e2->e_attrs; a; a=a->a_next ) {
|
||||
if ( a->a_vals ) {
|
||||
for (b=a->a_vals; !BER_BVISNULL( b ); b++,i++) {
|
||||
vals[i].bv_len = a->a_desc->ad_cname.bv_len + b->bv_len +3;
|
||||
vals[i].bv_val = ch_malloc( vals[i].bv_len+1 );
|
||||
ptr = lutil_strcopy( vals[i].bv_val,
|
||||
a->a_desc->ad_cname.bv_val );
|
||||
*ptr++ = ':';
|
||||
*ptr++ = '+';
|
||||
*ptr++ = ' ';
|
||||
AC_MEMCPY( ptr, b->bv_val, b->bv_len );
|
||||
vals[i].bv_val[vals[i].bv_len] = '\0';
|
||||
accesslog_val2val( a->a_desc, b, c_op, &vals[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
vals[i].bv_val = NULL;
|
||||
vals[i].bv_len = 0;
|
||||
a = attr_alloc( ad_reqMod );
|
||||
a = attr_alloc( logop == LOG_EN_ADD ? ad_reqMod : ad_reqOld );
|
||||
a->a_vals = vals;
|
||||
a->a_nvals = vals;
|
||||
last_attr->a_next = a;
|
||||
break;
|
||||
|
||||
case LOG_EN_DELETE:
|
||||
/* needs nothing else */
|
||||
break;
|
||||
}
|
||||
|
||||
case LOG_EN_MODIFY:
|
||||
/* count all the mods */
|
||||
@ -896,15 +946,24 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
|
||||
}
|
||||
vals = ch_malloc( (i+1) * sizeof( struct berval ));
|
||||
i = 0;
|
||||
|
||||
/* Zero flags on old entry */
|
||||
if ( old ) {
|
||||
for ( a=old->e_attrs; a; a=a->a_next )
|
||||
a->a_flags = 0;
|
||||
}
|
||||
|
||||
for ( m=op->orm_modlist; m; m=m->sml_next ) {
|
||||
/* Mark this attribute as modified */
|
||||
if ( old ) {
|
||||
a = attr_find( old->e_attrs, m->sml_desc );
|
||||
if ( a )
|
||||
a->a_flags = 1;
|
||||
}
|
||||
if ( m->sml_values ) {
|
||||
for (b=m->sml_values; !BER_BVISNULL( b ); b++,i++) {
|
||||
char c_op;
|
||||
vals[i].bv_len = m->sml_desc->ad_cname.bv_len + b->bv_len +3;
|
||||
vals[i].bv_val = ch_malloc( vals[i].bv_len+1 );
|
||||
ptr = lutil_strcopy( vals[i].bv_val,
|
||||
m->sml_desc->ad_cname.bv_val );
|
||||
*ptr++ = ':';
|
||||
|
||||
switch( m->sml_op ) {
|
||||
case LDAP_MOD_ADD: c_op = '+'; break;
|
||||
case LDAP_MOD_DELETE: c_op = '-'; break;
|
||||
@ -917,10 +976,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
|
||||
*/
|
||||
default: c_op = '?'; break;
|
||||
}
|
||||
*ptr++ = c_op;
|
||||
*ptr++ = ' ';
|
||||
AC_MEMCPY( ptr, b->bv_val, b->bv_len );
|
||||
vals[i].bv_val[vals[i].bv_len] = '\0';
|
||||
accesslog_val2val( m->sml_desc, b, c_op, &vals[i] );
|
||||
}
|
||||
} else if ( m->sml_op == LDAP_MOD_DELETE ) {
|
||||
vals[i].bv_len = m->sml_desc->ad_cname.bv_len + 2;
|
||||
@ -939,6 +995,34 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
|
||||
a->a_vals = vals;
|
||||
a->a_nvals = vals;
|
||||
last_attr->a_next = a;
|
||||
|
||||
if ( old ) {
|
||||
last_attr = a;
|
||||
/* count all the vals */
|
||||
i = 0;
|
||||
for ( a=old->e_attrs; a; a=a->a_next ) {
|
||||
if ( a->a_vals && a->a_flags ) {
|
||||
for (b=a->a_vals; !BER_BVISNULL( b ); b++) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
vals = ch_malloc( (i+1) * sizeof( struct berval ));
|
||||
i = 0;
|
||||
for ( a=old->e_attrs; a; a=a->a_next ) {
|
||||
if ( a->a_vals && a->a_flags ) {
|
||||
for (b=a->a_vals; !BER_BVISNULL( b ); b++,i++) {
|
||||
accesslog_val2val( a->a_desc, b, 0, &vals[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
vals[i].bv_val = NULL;
|
||||
vals[i].bv_len = 0;
|
||||
a = attr_alloc( ad_reqOld );
|
||||
a->a_vals = vals;
|
||||
a->a_nvals = vals;
|
||||
last_attr->a_next = a;
|
||||
}
|
||||
break;
|
||||
|
||||
case LOG_EN_MODRDN:
|
||||
@ -1043,6 +1127,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
|
||||
entry_free( e );
|
||||
|
||||
done:
|
||||
if ( old ) entry_free( old );
|
||||
ldap_pvt_thread_mutex_unlock( &li->li_log_mutex );
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
@ -1099,6 +1184,20 @@ accesslog_op_mod( Operation *op, SlapReply *rs )
|
||||
* overlays like refint to keep working.
|
||||
*/
|
||||
ldap_pvt_thread_mutex_lock( &li->li_op_mutex );
|
||||
if ( li->li_filter && ( op->o_tag == LDAP_REQ_DELETE ||
|
||||
op->o_tag == LDAP_REQ_MODIFY )) {
|
||||
int rc;
|
||||
Entry *e;
|
||||
|
||||
op->o_bd->bd_info = on->on_info->oi_orig;
|
||||
rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e );
|
||||
if ( e ) {
|
||||
if ( test_filter( op, e, li->li_filter ) == LDAP_COMPARE_TRUE )
|
||||
li->li_old = entry_dup( e );
|
||||
be_entry_release_rw( op, e, 0 );
|
||||
}
|
||||
op->o_bd->bd_info = (BackendInfo *)on;
|
||||
}
|
||||
}
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user