]> git.sur5r.net Git - openldap/commitdiff
More changes suggested by Quanah
authorKurt Zeilenga <kurt@openldap.org>
Tue, 9 May 2006 19:43:11 +0000 (19:43 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Tue, 9 May 2006 19:43:11 +0000 (19:43 +0000)
+       Added slapd syncrepl mandatory searchbase check
+       Fixed slapo-accesslog bugs
+       Added slapo-accesslog oldReq feature
+       Fixed slapo ppolicy BER tags
+       Fixed slapo-auditlog missing return codes
+       Fixed slurpd potential overflow issue
+       Fixed slapo-translucent modifications
+       Fixed libldap_r thread debug missing break

CHANGES
doc/man/man5/slapo-accesslog.5
libraries/libldap/ppolicy.c
libraries/libldap_r/thr_debug.c
servers/slapd/overlays/accesslog.c
servers/slapd/overlays/auditlog.c
servers/slapd/overlays/ppolicy.c
servers/slapd/overlays/translucent.c
servers/slapd/syncrepl.c
servers/slurpd/st.c

diff --git a/CHANGES b/CHANGES
index 4c1daca36e07f9f08f928d1950f3edaed3aa6343..0f089cdb5e1235b251d6c1b3e0cb69b763c895bc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -11,6 +11,14 @@ OpenLDAP 2.3.22 Engineering
        Fixed slapd thread pool init issue (ITS#4513)
        Fixed slapd cn=config olcLimits (ITS#4515)
        Fixed slapd runqueue use of freed memory (ITS#4517)
+       Added slapd syncrepl mandatory searchbase check
+       Fixed slapo-accesslog bugs
+       Added slapo-accesslog oldReq feature
+       Fixed slapo ppolicy BER tags
+       Fixed slapo-auditlog missing return codes
+       Fixed slurpd potential overflow issue
+       Fixed slapo-translucent modifications
+       Fixed libldap_r thread debug missing break
 
 OpenLDAP 2.3.21 Release
        Fixed libldap referral chasing issue (ITS#4448)
index 2a28cd82a4986e10e8901d019313717aa89035b2..1c2d6cfe1285d80cb9021f367349b91ee6f1e1e2 100644 (file)
@@ -49,6 +49,11 @@ abandon, bind, unbind
 all operations
 .RE
 .TP
+.B logold <filter>
+Specify a filter for matching against Deleted and Modified entries. If
+the entry matches the filter, the old contents of the entry will be
+logged along with the current request.
+.TP
 .B logpurge <age> <interval>
 Specify the maximum age for log entries to be retained in the database,
 and how often to scan the database for old entries. Both the
@@ -94,6 +99,7 @@ succeed or not. The default is FALSE.
        overlay accesslog
        logdb cn=log
        logops writes reads
+       logold (objectclass=person)
 .fi
 
 .SH SCHEMA
@@ -310,7 +316,12 @@ to its deletion. The values are formatted as
 attribute: value
 .RE
 .PD
-This option is not yet implemented.
+The
+.B reqOld
+attribute is only populated if the entry being deleted matches the
+configured
+.B logold
+filter.
 
 .LP
 .RS 4
@@ -329,7 +340,12 @@ attribute, which was already described above in the Add operation. It may
 optionally contain the previous contents of any modified attributes in the
 .B reqOld
 attribute, using the same format as described above for the Delete operation.
-This option is not yet implemented.
+The
+.B reqOld
+attribute is only populated if the entry being modified matches the
+configured
+.B logold
+filter.
 
 .LP
 .RS 4
index dd21aa99d529453b2c232000b27921a6a3fe538c..11a5a3b1a4483f3e3c72e755dc63932638705626 100644 (file)
 
 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
 
-#define PPOLICY_WARNING 0xa0L
-#define PPOLICY_ERROR 0xa1L
+/* IMPLICIT TAGS, all context-specific */
+#define PPOLICY_WARNING 0xa0L  /* constructed + 0 */
+#define PPOLICY_ERROR 0x81L    /* primitive + 1 */
 
-#define PPOLICY_EXPIRE 0xa0L
-#define PPOLICY_GRACE  0xa1L
+#define PPOLICY_EXPIRE 0x80L   /* primitive + 0 */
+#define PPOLICY_GRACE  0x81L   /* primitive + 1 */
 
 /*---
    ldap_create_passwordpolicy_control
index fac64616eb92a9fc7a7f55372418a1da59221282..f43c61e7fa6a5d7f470061f32197d6cd9ccaaa93 100644 (file)
@@ -455,6 +455,7 @@ adjust_count( int which, int adjust )
                resource_counts[which] += adjust;
                rc = ldap_int_thread_mutex_unlock( &resource_mutexes[which] );
                assert( rc == 0 );
+               break;
        case Count_reported:
                fputs( "...more ldap_debug_thread activity after exit...\n", stderr );
                count = Count_reported_more;
index bd61096dbbb9f8e01c5e267438b588eca0bc0c43..c0454cf20032caf170c73123af0d535b3c1d972c 100644 (file)
@@ -57,6 +57,8 @@ typedef struct log_info {
        int li_age;
        int li_cycle;
        struct re_s *li_task;
+       Filter *li_oldf;
+       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_OLD
 };
 
 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 },
+       { "logold", "filter", 2, 2, 0, ARG_MAGIC|LOG_OLD,
+               log_cf_gen, "( OLcfgOvAt:4.5 NAME 'olcAccessLogOld' "
+                       "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 $ "
+                       "olcAccessLogOld ) )",
                        Cft_Overlay, log_cfats },
        { NULL }
 };
@@ -396,29 +404,29 @@ log_age_parse(char *agestr)
                        return -1;
                t1 *= 24;
                gotdays = 1;
-       } else if ( *endptr != ':' ) {
-       /* No valid delimiter found, fail */
-               return -1;
+               agestr = endptr + 1;
+       } else {
+               if ( agestr[2] != ':' ) {
+                       /* No valid delimiter found, fail */
+                       return -1;
+               }
+               t1 *= 60;
+               agestr += 3;
        }
 
-       agestr += 3;
        t2 = atoi( agestr );
-
-       /* if there's a delimiter, it can only be a colon */
-       if ( agestr[2] && agestr[2] != ':' )
-               return -1;
-
-       /* If we're at the end of the string, and we started with days,
-        * fail because we expected to find minutes too.
-        */
-       if ( gotdays && !agestr[2] )
-               return -1;
-
-       t1 *= 60;
        t1 += t2;
 
-       if ( !agestr[2] )
-               return t1 * 60;
+       if ( agestr[2] ) {
+               /* if there's a delimiter, it can only be a colon */
+               if ( agestr[2] != ':' )
+                       return -1;
+       } else {
+               /* If we're at the end of the string, and we started with days,
+                * fail because we expected to find minutes too.
+                */
+               return gotdays ? -1 : t1 * 60;
+       }
 
        agestr += 3;
        t2 = atoi( agestr );
@@ -429,12 +437,15 @@ log_age_parse(char *agestr)
        t1 *= 60;
        t1 += t2;
 
-       t1 *= 60;
        if ( agestr[2] ) {
                agestr += 3;
                if ( agestr[2] )
                        return -1;
+               t1 *= 60;
                t1 += atoi( agestr );
+       } else if ( gotdays ) {
+               /* only got days+hh:mm */
+               t1 *= 60;
        }
        return t1;
 }
@@ -449,7 +460,7 @@ log_age_unparse( int age, struct berval *agebv )
        age /= 60;
        mm = age % 60;
        age /= 60;
-       hh = age % 60;
+       hh = age % 24;
        age /= 24;
        dd = age;
 
@@ -605,6 +616,14 @@ log_cf_gen(ConfigArgs *c)
                        else
                                rc = 1;
                        break;
+               case LOG_OLD:
+                       if ( li->li_oldf ) {
+                               filter2bv( li->li_oldf, &agebv );
+                               value_add_one( &c->rvalue_vals, &agebv );
+                       }
+                       else
+                               rc = 1;
+                       break;
                }
                break;
        case LDAP_MOD_DELETE:
@@ -635,6 +654,12 @@ log_cf_gen(ConfigArgs *c)
                case LOG_SUCCESS:
                        li->li_success = 0;
                        break;
+               case LOG_OLD:
+                       if ( li->li_oldf ) {
+                               filter_free( li->li_oldf );
+                               li->li_oldf = NULL;
+                       }
+                       break;
                }
                break;
        default:
@@ -680,6 +705,12 @@ log_cf_gen(ConfigArgs *c)
                case LOG_SUCCESS:
                        li->li_success = c->value_int;
                        break;
+               case LOG_OLD:
+                       li->li_oldf = str2filter( c->argv[1] );
+                       if ( !li->li_oldf ) {
+                               sprintf( c->msg, "bad filter!" );
+                               rc = 1;
+                       }
                }
                break;
        }
@@ -782,6 +813,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 +840,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
        int i;
        int logop;
        slap_verbmasks *lo;
-       Entry *e;
+       Entry *e = NULL, *old = NULL;
        char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE+8];
        struct berval bv;
        char *ptr;
@@ -821,6 +870,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 +895,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 +919,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 +949,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 +979,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 +998,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:
@@ -1040,10 +1127,12 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
        }
 
        op2.o_bd->be_add( &op2, &rs2 );
-       entry_free( e );
 
 done:
-       ldap_pvt_thread_mutex_unlock( &li->li_log_mutex );
+       if ( lo->mask & LOG_OP_WRITES )
+               ldap_pvt_thread_mutex_unlock( &li->li_log_mutex );
+       if ( e ) entry_free( e );
+       if ( old ) entry_free( old );
        return SLAP_CB_CONTINUE;
 }
 
@@ -1099,6 +1188,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_oldf && ( 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_oldf ) == 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;
 }
index c617bb02ba27763bc82dec6c0230ebbabc4e9dda..dd338bbfa7da1dc870e8507ab00085758c7db5f5 100644 (file)
@@ -177,6 +177,7 @@ auditlog_db_close(
 
        free( ad->ad_logfile );
        ad->ad_logfile = NULL;
+       return 0;
 }
 
 static int
@@ -189,6 +190,7 @@ auditlog_db_destroy(
 
        ldap_pvt_thread_mutex_destroy( &ad->ad_mutex );
        free( ad );
+       return 0;
 }
 
 static int
index bed5b4b366b60e4509401e6e5a5790b9370d1301..fb37f669ad8e6df895a6e7647f952f5a331cf7a0 100644 (file)
@@ -259,11 +259,12 @@ account_locked( Operation *op, Entry *e,
        return 0;
 }
 
-#define PPOLICY_WARNING 0xa0L
-#define PPOLICY_ERROR 0xa1L
+/* IMPLICIT TAGS, all context-specific */
+#define PPOLICY_WARNING 0xa0L  /* constructed + 0 */
+#define PPOLICY_ERROR 0x81L    /* primitive + 1 */
  
-#define PPOLICY_EXPIRE 0xa0L
-#define PPOLICY_GRACE  0xa1L
+#define PPOLICY_EXPIRE 0x80L   /* primitive + 0 */
+#define PPOLICY_GRACE  0x81L   /* primitive + 1 */
 
 static LDAPControl *
 create_passcontrol( int exptime, int grace, LDAPPasswordPolicyError err )
index eee8a6d40ce4a1d6c222ab631c4195bf39fe26d7..cc1357a57bcdba776ee0a626389ad6730e4361a8 100644 (file)
@@ -208,7 +208,8 @@ static int translucent_delete(Operation *op, SlapReply *rs) {
 static int
 translucent_tag_cb( Operation *op, SlapReply *rs )
 {
-       op->o_tag = (ber_tag_t)op->o_callback->sc_private;
+       op->o_tag = LDAP_REQ_MODIFY;
+       op->orm_modlist = op->o_callback->sc_private;
        rs->sr_tag = slap_req2res( op->o_tag );
 
        return SLAP_CB_CONTINUE;
@@ -400,7 +401,7 @@ release:
        glue_parent(&nop);
 
        cb.sc_response = translucent_tag_cb;
-       cb.sc_private = (void *)LDAP_REQ_MODIFY;
+       cb.sc_private = op->orm_modlist;
        cb.sc_next = nop.o_callback;
        nop.o_callback = &cb;
        rc = on->on_info->oi_orig->bi_op_add(&nop, &nrs);
index f19e0a99937c4363b28553995ba3ff5356131eae..68dcf4e0e481b517e317879ad0435ae50bd45424 100644 (file)
@@ -2704,9 +2704,10 @@ syncinfo_free( syncinfo_t *sie )
 /* mandatory */
 #define GOT_ID                 0x0001
 #define GOT_PROVIDER           0x0002
+#define GOT_BASE               0x0004
 
 /* check */
-#define GOT_ALL                        (GOT_ID|GOT_PROVIDER)
+#define GOT_ALL                        (GOT_ID|GOT_PROVIDER|GOT_BASE)
 
 static struct {
        struct berval key;
@@ -2811,6 +2812,7 @@ parse_syncrepl_line(
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
                                return -1;
                        }
+                       gots |= GOT_BASE;
                } else if ( !strncasecmp( c->argv[ i ], LOGBASESTR "=",
                                        STRLENOF( LOGBASESTR "=" ) ) )
                {
@@ -3127,7 +3129,10 @@ parse_syncrepl_line(
 
        if ( gots != GOT_ALL ) {
                snprintf( c->msg, sizeof( c->msg ),
-                       "Error: Malformed \"syncrepl\" line in slapd config file" );
+                       "Error: Malformed \"syncrepl\" line in slapd config file, missing%s%s%s",
+                       gots & GOT_ID ? "" : " "IDSTR,
+                       gots & GOT_PROVIDER ? "" : " "PROVIDERSTR,
+                       gots & GOT_BASE ? "" : " "SEARCHBASESTR );
                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
                return -1;
        }
index 595b99ea0f87cc5df9d935a458e55f50af8e2b88..8deaa61c70c1ee6446da8e60f1c30f6e1eba5aca 100644 (file)
@@ -246,10 +246,9 @@ St_read(
        }
        if ( found ) {
            char tbuf[ 255 ];
-           sprintf( tbuf, "%s:%s (timestamp %s.%s)", hostname, port,
-                   timestamp, seq );
+           sprintf( tbuf, "%s.%s", timestamp, seq );
            Debug( LDAP_DEBUG_ARGS,
-                   "Retrieved state information for %s\n", tbuf, 0, 0 );
+                   "Retrieved state information for %s:%s (timestamp %s)\n", hostname, port, tbuf );
        } else {
            Debug(  LDAP_DEBUG_ANY,
                    "Warning: saved state for %s:%s, not a known replica\n",