Diff for /servers/slapd/overlays/accesslog.c between versions 1.2.2.8 and 1.2.2.9

version 1.2.2.8, 2005/10/12 21:33:53 version 1.2.2.9, 2005/11/03 18:03:02
Line 1 Line 1
 /* accesslog.c - log operations for audit/history purposes */  /* accesslog.c - log operations for audit/history purposes */
 /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/accesslog.c,v 1.2.2.7 2005/10/11 17:42:19 kurt Exp $ */  /* $OpenLDAP: pkg/ldap/servers/slapd/overlays/accesslog.c,v 1.27 2005/10/28 01:31:04 hyc Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
  * Copyright 2005 The OpenLDAP Foundation.   * Copyright 2005 The OpenLDAP Foundation.
Line 58  typedef struct log_info { Line 58  typedef struct log_info {
         int li_cycle;          int li_cycle;
         struct re_s *li_task;          struct re_s *li_task;
         int li_success;          int li_success;
           ldap_pvt_thread_mutex_t li_op_mutex;
           ldap_pvt_thread_mutex_t li_log_mutex;
 } log_info;  } log_info;
   
 static ConfigDriver log_cf_gen;  static ConfigDriver log_cf_gen;
Line 139  enum { Line 141  enum {
         LOG_EN__COUNT          LOG_EN__COUNT
 };  };
   
 static ObjectClass *log_ocs[LOG_EN__COUNT];  static ObjectClass *log_ocs[LOG_EN__COUNT], *log_container;
   
 #define LOG_SCHEMA_ROOT "1.3.6.1.4.1.4203.666.11.5"  #define LOG_SCHEMA_ROOT "1.3.6.1.4.1.4203.666.11.5"
   
Line 152  static AttributeDescription *ad_reqDN, * Line 154  static AttributeDescription *ad_reqDN, *
         *ad_reqNewSuperior, *ad_reqDeleteOldRDN, *ad_reqMod,          *ad_reqNewSuperior, *ad_reqDeleteOldRDN, *ad_reqMod,
         *ad_reqScope, *ad_reqFilter, *ad_reqAttr, *ad_reqEntries,          *ad_reqScope, *ad_reqFilter, *ad_reqAttr, *ad_reqEntries,
         *ad_reqSizeLimit, *ad_reqTimeLimit, *ad_reqAttrsOnly, *ad_reqData,          *ad_reqSizeLimit, *ad_reqTimeLimit, *ad_reqAttrsOnly, *ad_reqData,
         *ad_reqId, *ad_reqMessage;          *ad_reqId, *ad_reqMessage, *ad_reqVersion, *ad_reqDerefAliases,
 #if 0          *ad_reqReferral, *ad_reqOld;
 static AttributeDescription *ad_oldest;  
 #endif  
   
 static struct {  static struct {
         char *at;          char *at;
Line 188  static struct { Line 188  static struct {
                 "EQUALITY caseIgnoreMatch "                  "EQUALITY caseIgnoreMatch "
                 "SYNTAX OMsDirectoryString "                  "SYNTAX OMsDirectoryString "
                 "SINGLE-VALUE )", &ad_reqSession },                  "SINGLE-VALUE )", &ad_reqSession },
         { "( " LOG_SCHEMA_AT ".6 NAME 'reqResult' "          { "( " LOG_SCHEMA_AT ".6 NAME 'reqAuthzID' "
                 "DESC 'Result code of request' "  
                 "EQUALITY integerMatch "  
                 "SYNTAX OMsInteger "  
                 "SINGLE-VALUE )", &ad_reqResult },  
         { "( " LOG_SCHEMA_AT ".7 NAME 'reqAuthzID' "  
                 "DESC 'Authorization ID of requestor' "                  "DESC 'Authorization ID of requestor' "
                 "EQUALITY distinguishedNameMatch "                  "EQUALITY distinguishedNameMatch "
                 "SYNTAX OMsDN "                  "SYNTAX OMsDN "
                 "SINGLE-VALUE )", &ad_reqAuthzID },                  "SINGLE-VALUE )", &ad_reqAuthzID },
         { "( " LOG_SCHEMA_AT ".8 NAME 'reqControls' "          { "( " LOG_SCHEMA_AT ".7 NAME 'reqResult' "
                   "DESC 'Result code of request' "
                   "EQUALITY integerMatch "
                   "ORDERING integerOrderingMatch "
                   "SYNTAX OMsInteger "
                   "SINGLE-VALUE )", &ad_reqResult },
           { "( " LOG_SCHEMA_AT ".8 NAME 'reqMessage' "
                   "DESC 'Error text of request' "
                   "EQUALITY caseIgnoreMatch "
                   "SUBSTR caseIgnoreSubstringsMatch "
                   "SYNTAX OMsDirectoryString "
                   "SINGLE-VALUE )", &ad_reqMessage },
           { "( " LOG_SCHEMA_AT ".9 NAME 'reqReferral' "
                   "DESC 'Referrals returned for request' "
                   "SUP labeledURI )", &ad_reqReferral },
           { "( " LOG_SCHEMA_AT ".10 NAME 'reqControls' "
                 "DESC 'Request controls' "                  "DESC 'Request controls' "
                 "SYNTAX OMsOctetString )", &ad_reqControls },                  "SYNTAX OMsOctetString )", &ad_reqControls },
         { "( " LOG_SCHEMA_AT ".9 NAME 'reqRespControls' "          { "( " LOG_SCHEMA_AT ".11 NAME 'reqRespControls' "
                 "DESC 'Response controls of request' "                  "DESC 'Response controls of request' "
                 "SYNTAX OMsOctetString )", &ad_reqRespControls },                  "SYNTAX OMsOctetString )", &ad_reqRespControls },
         { "( " LOG_SCHEMA_AT ".10 NAME 'reqMethod' "          { "( " LOG_SCHEMA_AT ".12 NAME 'reqId' "
                   "DESC 'ID of Request to Abandon' "
                   "EQUALITY integerMatch "
                   "ORDERING integerOrderingMatch "
                   "SYNTAX OMsInteger "
                   "SINGLE-VALUE )", &ad_reqId },
           { "( " LOG_SCHEMA_AT ".13 NAME 'reqVersion' "
                   "DESC 'Protocol version of Bind request' "
                   "EQUALITY integerMatch "
                   "ORDERING integerOrderingMatch "
                   "SYNTAX OMsInteger "
                   "SINGLE-VALUE )", &ad_reqVersion },
           { "( " LOG_SCHEMA_AT ".14 NAME 'reqMethod' "
                 "DESC 'Bind method of request' "                  "DESC 'Bind method of request' "
                 "EQUALITY caseIgnoreMatch "                  "EQUALITY caseIgnoreMatch "
                 "SYNTAX OMsDirectoryString "                  "SYNTAX OMsDirectoryString "
                 "SINGLE-VALUE )", &ad_reqMethod },                  "SINGLE-VALUE )", &ad_reqMethod },
         { "( " LOG_SCHEMA_AT ".11 NAME 'reqAssertion' "          { "( " LOG_SCHEMA_AT ".15 NAME 'reqAssertion' "
                 "DESC 'Compare Assertion of request' "                  "DESC 'Compare Assertion of request' "
                 "SYNTAX OMsDirectoryString "                  "SYNTAX OMsDirectoryString "
                 "SINGLE-VALUE )", &ad_reqAssertion },                  "SINGLE-VALUE )", &ad_reqAssertion },
         { "( " LOG_SCHEMA_AT ".12 NAME 'reqNewRDN' "          { "( " LOG_SCHEMA_AT ".16 NAME 'reqMod' "
                   "DESC 'Modifications of request' "
                   "EQUALITY octetStringMatch "
                   "SUBSTR octetStringSubstringsMatch "
                   "SYNTAX OMsOctetString )", &ad_reqMod },
           { "( " LOG_SCHEMA_AT ".17 NAME 'reqOld' "
                   "DESC 'Old values of entry before request completed' "
                   "EQUALITY octetStringMatch "
                   "SUBSTR octetStringSubstringsMatch "
                   "SYNTAX OMsOctetString )", &ad_reqOld },
           { "( " LOG_SCHEMA_AT ".18 NAME 'reqNewRDN' "
                 "DESC 'New RDN of request' "                  "DESC 'New RDN of request' "
                 "EQUALITY distinguishedNameMatch "                  "EQUALITY distinguishedNameMatch "
                 "SYNTAX OMsDN "                  "SYNTAX OMsDN "
                 "SINGLE-VALUE )", &ad_reqNewRDN },                  "SINGLE-VALUE )", &ad_reqNewRDN },
         { "( " LOG_SCHEMA_AT ".13 NAME 'reqNewSuperior' "          { "( " LOG_SCHEMA_AT ".19 NAME 'reqDeleteOldRDN' "
                   "DESC 'Delete old RDN' "
                   "EQUALITY booleanMatch "
                   "SYNTAX OMsBoolean "
                   "SINGLE-VALUE )", &ad_reqDeleteOldRDN },
           { "( " LOG_SCHEMA_AT ".20 NAME 'reqNewSuperior' "
                 "DESC 'New superior DN of request' "                  "DESC 'New superior DN of request' "
                 "EQUALITY distinguishedNameMatch "                  "EQUALITY distinguishedNameMatch "
                 "SYNTAX OMsDN "                  "SYNTAX OMsDN "
                 "SINGLE-VALUE )", &ad_reqNewSuperior },                  "SINGLE-VALUE )", &ad_reqNewSuperior },
         { "( " LOG_SCHEMA_AT ".14 NAME 'reqDeleteOldRDN' "          { "( " LOG_SCHEMA_AT ".21 NAME 'reqScope' "
                 "DESC 'Delete old RDN' "  
                 "SYNTAX OMsBoolean "  
                 "SINGLE-VALUE )", &ad_reqDeleteOldRDN },  
         { "( " LOG_SCHEMA_AT ".15 NAME 'reqMod' "  
                 "DESC 'Modifications of request' "  
                 "SYNTAX OMsDirectoryString "  
                 "EQUALITY caseIgnoreMatch "  
                 "SUBSTR caseIgnoreSubstringsMatch )", &ad_reqMod },  
         { "( " LOG_SCHEMA_AT ".16 NAME 'reqScope' "  
                 "DESC 'Scope of request' "                  "DESC 'Scope of request' "
                   "EQUALITY caseIgnoreMatch "
                 "SYNTAX OMsDirectoryString "                  "SYNTAX OMsDirectoryString "
                 "SINGLE-VALUE )", &ad_reqScope },                  "SINGLE-VALUE )", &ad_reqScope },
         { "( " LOG_SCHEMA_AT ".17 NAME 'reqFilter' "          { "( " LOG_SCHEMA_AT ".22 NAME 'reqDerefAliases' "
                   "DESC 'Disposition of Aliases in request' "
                   "EQUALITY caseIgnoreMatch "
                   "SYNTAX OMsDirectoryString "
                   "SINGLE-VALUE )", &ad_reqDerefAliases },
           { "( " LOG_SCHEMA_AT ".23 NAME 'reqAttrsOnly' "
                   "DESC 'Attributes and values of request' "
                   "EQUALITY booleanMatch "
                   "SYNTAX OMsBoolean "
                   "SINGLE-VALUE )", &ad_reqAttrsOnly },
           { "( " LOG_SCHEMA_AT ".24 NAME 'reqFilter' "
                 "DESC 'Filter of request' "                  "DESC 'Filter of request' "
                   "EQUALITY caseIgnoreMatch "
                   "SUBSTR caseIgnoreSubstringsMatch "
                 "SYNTAX OMsDirectoryString "                  "SYNTAX OMsDirectoryString "
                 "SINGLE-VALUE )", &ad_reqFilter },                  "SINGLE-VALUE )", &ad_reqFilter },
         { "( " LOG_SCHEMA_AT ".18 NAME 'reqAttr' "          { "( " LOG_SCHEMA_AT ".25 NAME 'reqAttr' "
                 "DESC 'Attributes of request' "                  "DESC 'Attributes of request' "
                   "EQUALITY caseIgnoreMatch "
                 "SYNTAX OMsDirectoryString )", &ad_reqAttr },                  "SYNTAX OMsDirectoryString )", &ad_reqAttr },
         { "( " LOG_SCHEMA_AT ".19 NAME 'reqEntries' "          { "( " LOG_SCHEMA_AT ".26 NAME 'reqSizeLimit' "
                 "DESC 'Number of entries returned' "  
                 "SYNTAX OMsInteger "  
                 "SINGLE-VALUE )", &ad_reqEntries },  
         { "( " LOG_SCHEMA_AT ".20 NAME 'reqSizeLimit' "  
                 "DESC 'Size limit of request' "                  "DESC 'Size limit of request' "
                   "EQUALITY integerMatch "
                   "ORDERING integerOrderingMatch "
                 "SYNTAX OMsInteger "                  "SYNTAX OMsInteger "
                 "SINGLE-VALUE )", &ad_reqSizeLimit },                  "SINGLE-VALUE )", &ad_reqSizeLimit },
         { "( " LOG_SCHEMA_AT ".21 NAME 'reqTimeLimit' "          { "( " LOG_SCHEMA_AT ".27 NAME 'reqTimeLimit' "
                 "DESC 'Time limit of request' "                  "DESC 'Time limit of request' "
                   "EQUALITY integerMatch "
                   "ORDERING integerOrderingMatch "
                 "SYNTAX OMsInteger "                  "SYNTAX OMsInteger "
                 "SINGLE-VALUE )", &ad_reqTimeLimit },                  "SINGLE-VALUE )", &ad_reqTimeLimit },
         { "( " LOG_SCHEMA_AT ".22 NAME 'reqAttrsOnly' "          { "( " LOG_SCHEMA_AT ".28 NAME 'reqEntries' "
                 "DESC 'Attributes and values of request' "                  "DESC 'Number of entries returned' "
                 "SYNTAX OMsBoolean "                  "EQUALITY integerMatch "
                 "SINGLE-VALUE )", &ad_reqAttrsOnly },                  "ORDERING integerOrderingMatch "
         { "( " LOG_SCHEMA_AT ".23 NAME 'reqData' "                  "SYNTAX OMsInteger "
                   "SINGLE-VALUE )", &ad_reqEntries },
           { "( " LOG_SCHEMA_AT ".29 NAME 'reqData' "
                 "DESC 'Data of extended request' "                  "DESC 'Data of extended request' "
                   "EQUALITY octetStringMatch "
                   "SUBSTR octetStringSubstringsMatch "
                 "SYNTAX OMsOctetString "                  "SYNTAX OMsOctetString "
                 "SINGLE-VALUE )", &ad_reqData },                  "SINGLE-VALUE )", &ad_reqData },
         { "( " LOG_SCHEMA_AT ".24 NAME 'reqId' "  
                 "DESC 'ID of Request to Abandon' "  
                 "SYNTAX OMsInteger "  
                 "SINGLE-VALUE )", &ad_reqId },  
         { "( " LOG_SCHEMA_AT ".25 NAME 'reqMessage' "  
                 "DESC 'Error text of request' "  
                 "SYNTAX OMsDirectoryString "  
                 "SINGLE-VALUE )", &ad_reqMessage },  
 #if 0  
         { "( " LOG_SCHEMA_AT ".26 NAME 'auditOldest' "  
                 "DESC 'Oldest record in this branch' "  
                 "EQUALITY generalizedTimeMatch "  
                 "ORDERING generalizedTimeOrderingMatch "  
                 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "  
                 "SINGLE-VALUE )", &ad_oldest },  
 #endif  
         { NULL, NULL }          { NULL, NULL }
 };  };
   
Line 286  static struct { Line 316  static struct {
         char *ot;          char *ot;
         ObjectClass **oc;          ObjectClass **oc;
 } locs[] = {  } locs[] = {
 #if 0  
         { "( " LOG_SCHEMA_OC ".0 NAME 'auditContainer' "          { "( " LOG_SCHEMA_OC ".0 NAME 'auditContainer' "
                   "DESC 'AuditLog container' "
                 "SUP top STRUCTURAL "                  "SUP top STRUCTURAL "
                 "MUST auditOldest "                  "MAY ( cn $ reqStart $ reqEnd ) )", &log_container },
                 "MAY cn )", &oc_container },  
 #endif  
         { "( " LOG_SCHEMA_OC ".1 NAME 'auditObject' "          { "( " LOG_SCHEMA_OC ".1 NAME 'auditObject' "
                 "DESC 'OpenLDAP request auditing' "                  "DESC 'OpenLDAP request auditing' "
                 "SUP top STRUCTURAL "                  "SUP top STRUCTURAL "
                 "MUST ( reqStart $ reqType $ reqSession ) "                  "MUST ( reqStart $ reqType $ reqSession ) "
                 "MAY ( reqDN $ reqAuthzID $ reqControls $ reqRespControls $ reqEnd $ "                  "MAY ( reqDN $ reqAuthzID $ reqControls $ reqRespControls $ reqEnd $ "
                         "reqResult $ reqMessage ) )", &log_ocs[LOG_EN_UNBIND] },                          "reqResult $ reqMessage $ reqReferral ) )",
                                   &log_ocs[LOG_EN_UNBIND] },
         { "( " LOG_SCHEMA_OC ".2 NAME 'auditReadObject' "          { "( " LOG_SCHEMA_OC ".2 NAME 'auditReadObject' "
                 "DESC 'OpenLDAP read request record' "                  "DESC 'OpenLDAP read request record' "
                 "SUP auditObject STRUCTURAL )", NULL },                  "SUP auditObject STRUCTURAL )", NULL },
         { "( " LOG_SCHEMA_OC ".3 NAME 'auditWriteObject' "          { "( " LOG_SCHEMA_OC ".3 NAME 'auditWriteObject' "
                 "DESC 'OpenLDAP write request record' "                  "DESC 'OpenLDAP write request record' "
                 "SUP auditObject STRUCTURAL )", &log_ocs[LOG_EN_DELETE] },                  "SUP auditObject STRUCTURAL )", NULL },
         { "( " LOG_SCHEMA_OC ".4 NAME 'auditAbandon' "          { "( " LOG_SCHEMA_OC ".4 NAME 'auditAbandon' "
                 "DESC 'Abandon operation' "                  "DESC 'Abandon operation' "
                 "SUP auditObject STRUCTURAL "                  "SUP auditObject STRUCTURAL "
Line 315  static struct { Line 344  static struct {
         { "( " LOG_SCHEMA_OC ".6 NAME 'auditBind' "          { "( " LOG_SCHEMA_OC ".6 NAME 'auditBind' "
                 "DESC 'Bind operation' "                  "DESC 'Bind operation' "
                 "SUP auditObject STRUCTURAL "                  "SUP auditObject STRUCTURAL "
                 "MUST reqMethod )", &log_ocs[LOG_EN_BIND] },                  "MUST ( reqVersion $ reqMethod ) )", &log_ocs[LOG_EN_BIND] },
         { "( " LOG_SCHEMA_OC ".7 NAME 'auditCompare' "          { "( " LOG_SCHEMA_OC ".7 NAME 'auditCompare' "
                 "DESC 'Compare operation' "                  "DESC 'Compare operation' "
                 "SUP auditReadObject STRUCTURAL "                  "SUP auditReadObject STRUCTURAL "
                 "MUST reqAssertion )", &log_ocs[LOG_EN_COMPARE] },                  "MUST reqAssertion )", &log_ocs[LOG_EN_COMPARE] },
         { "( " LOG_SCHEMA_OC ".8 NAME 'auditModify' "          { "( " LOG_SCHEMA_OC ".8 NAME 'auditDelete' "
                   "DESC 'Delete operation' "
                   "SUP auditWriteObject STRUCTURAL "
                   "MAY reqOld )", &log_ocs[LOG_EN_DELETE] },
           { "( " LOG_SCHEMA_OC ".9 NAME 'auditModify' "
                 "DESC 'Modify operation' "                  "DESC 'Modify operation' "
                 "SUP auditWriteObject STRUCTURAL "                  "SUP auditWriteObject STRUCTURAL "
                 "MUST reqMod )", &log_ocs[LOG_EN_MODIFY] },                  "MAY reqOld MUST reqMod )", &log_ocs[LOG_EN_MODIFY] },
         { "( " LOG_SCHEMA_OC ".9 NAME 'auditModRDN' "          { "( " LOG_SCHEMA_OC ".10 NAME 'auditModRDN' "
                 "DESC 'ModRDN operation' "                  "DESC 'ModRDN operation' "
                 "SUP auditWriteObject STRUCTURAL "                  "SUP auditWriteObject STRUCTURAL "
                 "MUST ( reqNewRDN $ reqDeleteOldRDN ) "                  "MUST ( reqNewRDN $ reqDeleteOldRDN ) "
                 "MAY reqNewSuperior )", &log_ocs[LOG_EN_MODRDN] },                  "MAY reqNewSuperior )", &log_ocs[LOG_EN_MODRDN] },
         { "( " LOG_SCHEMA_OC ".10 NAME 'auditSearch' "          { "( " LOG_SCHEMA_OC ".11 NAME 'auditSearch' "
                 "DESC 'Search operation' "                  "DESC 'Search operation' "
                 "SUP auditReadObject STRUCTURAL "                  "SUP auditReadObject STRUCTURAL "
                 "MUST ( reqScope $ reqAttrsonly ) "                  "MUST ( reqScope $ reqDerefAliases $ reqAttrsonly ) "
                 "MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $ "                  "MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $ "
                         "reqTimeLimit ) )", &log_ocs[LOG_EN_SEARCH] },                          "reqTimeLimit ) )", &log_ocs[LOG_EN_SEARCH] },
         { "( " LOG_SCHEMA_OC ".11 NAME 'auditExtended' "          { "( " LOG_SCHEMA_OC ".12 NAME 'auditExtended' "
                 "DESC 'Extended operation' "                  "DESC 'Extended operation' "
                 "SUP auditObject STRUCTURAL "                  "SUP auditObject STRUCTURAL "
                 "MAY reqData )", &log_ocs[LOG_EN_EXTENDED] },                  "MAY reqData )", &log_ocs[LOG_EN_EXTENDED] },
Line 344  static struct { Line 377  static struct {
   
 #define RDNEQ   "reqStart="  #define RDNEQ   "reqStart="
   
 /* Our time intervals are of the form [dd+]hh:mm[:ss]  /* Our time intervals are of the form [ddd+]hh:mm[:ss]
  * If a field is present, it must be two digits. We assume no one   * If a field is present, it must be two digits. (Except for
  * will want to keep log records for longer than 99 days.   * days, which can be arbitrary width.)
  */   */
 static int  static int
 log_age_parse(char *agestr)  log_age_parse(char *agestr)
 {  {
         int t1, t2;          int t1, t2;
         int gotdays = 0;          int gotdays = 0;
           char *endptr;
   
         t1 = atoi( agestr );          t1 = strtol( agestr, &endptr, 10 );
         /* Is there a days delimiter? */          /* Is there a days delimiter? */
         if ( agestr[2] == '+' ) {          if ( *endptr == '+' ) {
                   /* 32 bit time only covers about 68 years */
                   if ( t1 < 0 || t1 > 25000 )
                           return -1;
                 t1 *= 24;                  t1 *= 24;
                 gotdays = 1;                  gotdays = 1;
         } else if ( agestr[2] != ':' ) {          } else if ( *endptr != ':' ) {
         /* No valid delimiter found, fail */          /* No valid delimiter found, fail */
                 return -1;                  return -1;
         }          }
Line 419  log_age_unparse( int age, struct berval Line 456  log_age_unparse( int age, struct berval
         ptr = agebv->bv_val;          ptr = agebv->bv_val;
   
         if ( dd )           if ( dd ) 
                 ptr += sprintf( ptr, "%02d+", dd );                  ptr += sprintf( ptr, "%d+", dd );
         ptr += sprintf( ptr, "%02d:%02d", hh, mm );          ptr += sprintf( ptr, "%02d:%02d", hh, mm );
         if ( ss )          if ( ss )
                 ptr += sprintf( ptr, ":%02d", ss );                  ptr += sprintf( ptr, ":%02d", ss );
Line 539  log_cf_gen(ConfigArgs *c) Line 576  log_cf_gen(ConfigArgs *c)
         struct log_info *li = on->on_bi.bi_private;          struct log_info *li = on->on_bi.bi_private;
         int rc = 0;          int rc = 0;
         slap_mask_t tmask = 0;          slap_mask_t tmask = 0;
         char agebuf[2*STRLENOF("dd+hh:mm:ss  ")];          char agebuf[2*STRLENOF("ddddd+hh:mm:ss  ")];
         struct berval agebv, cyclebv;          struct berval agebv, cyclebv;
   
         switch( c->op ) {          switch( c->op ) {
Line 649  log_cf_gen(ConfigArgs *c) Line 686  log_cf_gen(ConfigArgs *c)
         return rc;          return rc;
 }  }
   
 static Entry *accesslog_entry( Operation *op, int logop ) {  static Entry *accesslog_entry( Operation *op, int logop,
           Operation *op2 ) {
         slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;          slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
         log_info *li = on->on_bi.bi_private;          log_info *li = on->on_bi.bi_private;
   
Line 690  static Entry *accesslog_entry( Operation Line 728  static Entry *accesslog_entry( Operation
         attr_merge_one( e, ad_reqStart, &timestamp, &ntimestamp );          attr_merge_one( e, ad_reqStart, &timestamp, &ntimestamp );
         op->o_tmpfree( ntimestamp.bv_val, op->o_tmpmemctx );          op->o_tmpfree( ntimestamp.bv_val, op->o_tmpmemctx );
   
           slap_op_time( &op2->o_time, &op2->o_tincr );
   
           timestamp.bv_len = sizeof(rdnbuf) - STRLENOF(RDNEQ);
           slap_timestamp( &op2->o_time, &timestamp );
           sprintf( timestamp.bv_val + timestamp.bv_len-1, ".%06dZ", op2->o_tincr );
           timestamp.bv_len += 7;
   
           attr_merge_normalize_one( e, ad_reqEnd, &timestamp, op->o_tmpmemctx );
   
         /* Exops have OID appended */          /* Exops have OID appended */
         if ( logop == LOG_EN_EXTENDED ) {          if ( logop == LOG_EN_EXTENDED ) {
                 bv.bv_len = lo->word.bv_len + op->ore_reqoid.bv_len + 2;                  bv.bv_len = lo->word.bv_len + op->ore_reqoid.bv_len + 2;
Line 721  static Entry *accesslog_entry( Operation Line 768  static Entry *accesslog_entry( Operation
   
 static struct berval scopes[] = {  static struct berval scopes[] = {
         BER_BVC("base"),          BER_BVC("base"),
         BER_BVC("onelevel"),          BER_BVC("one"),
         BER_BVC("subtree"),          BER_BVC("sub"),
         BER_BVC("subordinate")          BER_BVC("subord")
   };
   
   static struct berval derefs[] = {
           BER_BVC("never"),
           BER_BVC("searching"),
           BER_BVC("finding"),
           BER_BVC("always")
 };  };
   
 static struct berval simple = BER_BVC("SIMPLE");  static struct berval simple = BER_BVC("SIMPLE");
Line 734  static int accesslog_response(Operation Line 788  static int accesslog_response(Operation
         Attribute *a, *last_attr;          Attribute *a, *last_attr;
         Modifications *m;          Modifications *m;
         struct berval *b;          struct berval *b;
         time_t endtime;  
         int i;          int i;
         int logop;          int logop;
         slap_verbmasks *lo;          slap_verbmasks *lo;
         Entry *e;          Entry *e;
         char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE];          char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE+8];
         struct berval bv;          struct berval bv;
         char *ptr;          char *ptr;
         BerVarray vals;          BerVarray vals;
Line 749  static int accesslog_response(Operation Line 802  static int accesslog_response(Operation
         if ( rs->sr_type != REP_RESULT && rs->sr_type != REP_EXTENDED )          if ( rs->sr_type != REP_RESULT && rs->sr_type != REP_EXTENDED )
                 return SLAP_CB_CONTINUE;                  return SLAP_CB_CONTINUE;
   
         if ( li->li_success && rs->sr_err != LDAP_SUCCESS )  
                 return SLAP_CB_CONTINUE;  
   
         switch ( op->o_tag ) {          switch ( op->o_tag ) {
         case LDAP_REQ_ADD:              logop = LOG_EN_ADD; break;          case LDAP_REQ_ADD:              logop = LOG_EN_ADD; break;
         case LDAP_REQ_DELETE:   logop = LOG_EN_DELETE; break;          case LDAP_REQ_DELETE:   logop = LOG_EN_DELETE; break;
Line 769  static int accesslog_response(Operation Line 819  static int accesslog_response(Operation
         if ( !( li->li_ops & lo->mask ))          if ( !( li->li_ops & lo->mask ))
                 return SLAP_CB_CONTINUE;                  return SLAP_CB_CONTINUE;
   
         endtime = slap_get_time();          if ( lo->mask & LOG_OP_WRITES ) {
                   ldap_pvt_thread_mutex_lock( &li->li_log_mutex );
         e = accesslog_entry( op, logop );                  ldap_pvt_thread_mutex_unlock( &li->li_op_mutex );
           }
   
         bv.bv_val = timebuf;          if ( li->li_success && rs->sr_err != LDAP_SUCCESS )
         bv.bv_len = sizeof(timebuf);                  goto done;
         slap_timestamp( &endtime, &bv );  
   
         attr_merge_one( e, ad_reqEnd, &bv, NULL );          e = accesslog_entry( op, logop, &op2 );
   
         attr_merge_one( e, ad_reqDN, &op->o_req_dn, &op->o_req_ndn );          attr_merge_one( e, ad_reqDN, &op->o_req_dn, &op->o_req_ndn );
   
Line 915  static int accesslog_response(Operation Line 965  static int accesslog_response(Operation
   
         case LOG_EN_SEARCH:          case LOG_EN_SEARCH:
                 attr_merge_one( e, ad_reqScope, &scopes[op->ors_scope], NULL );                  attr_merge_one( e, ad_reqScope, &scopes[op->ors_scope], NULL );
                   attr_merge_one( e, ad_reqDerefAliases, &derefs[op->ors_deref], NULL );
                 attr_merge_one( e, ad_reqAttrsOnly, op->ors_attrsonly ?                  attr_merge_one( e, ad_reqAttrsOnly, op->ors_attrsonly ?
                         (struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv,                          (struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv,
                         NULL );                          NULL );
Line 943  static int accesslog_response(Operation Line 994  static int accesslog_response(Operation
                 break;                  break;
   
         case LOG_EN_BIND:          case LOG_EN_BIND:
                   bv.bv_val = timebuf;
                   bv.bv_len = sprintf( bv.bv_val, "%d", op->o_protocol );
                   attr_merge_one( e, ad_reqVersion, &bv, NULL );
                 if ( op->orb_method == LDAP_AUTH_SIMPLE ) {                  if ( op->orb_method == LDAP_AUTH_SIMPLE ) {
                         attr_merge_one( e, ad_reqMethod, &simple, NULL );                          attr_merge_one( e, ad_reqMethod, &simple, NULL );
                 } else {                  } else {
Line 955  static int accesslog_response(Operation Line 1009  static int accesslog_response(Operation
                         attr_merge_one( e, ad_reqMethod, &bv, NULL );                          attr_merge_one( e, ad_reqMethod, &bv, NULL );
                         op->o_tmpfree( bv.bv_val, op->o_tmpmemctx );                          op->o_tmpfree( bv.bv_val, op->o_tmpmemctx );
                 }                  }
   
                 break;                  break;
   
         case LOG_EN_EXTENDED:          case LOG_EN_EXTENDED:
Line 970  static int accesslog_response(Operation Line 1025  static int accesslog_response(Operation
   
         op2.o_hdr = op->o_hdr;          op2.o_hdr = op->o_hdr;
         op2.o_tag = LDAP_REQ_ADD;          op2.o_tag = LDAP_REQ_ADD;
         op2.o_time = endtime;  
         op2.o_tincr = 0;  
         op2.o_bd = li->li_db;          op2.o_bd = li->li_db;
         op2.o_dn = li->li_db->be_rootdn;          op2.o_dn = li->li_db->be_rootdn;
         op2.o_ndn = li->li_db->be_rootndn;          op2.o_ndn = li->li_db->be_rootndn;
Line 980  static int accesslog_response(Operation Line 1033  static int accesslog_response(Operation
         op2.ora_e = e;          op2.ora_e = e;
         op2.o_callback = &nullsc;          op2.o_callback = &nullsc;
   
         if ( lo->mask & LOG_OP_WRITES ) {          if (( lo->mask & LOG_OP_WRITES ) && !BER_BVISEMPTY( &op->o_csn )) {
                 slap_get_commit_csn( op, NULL, &bv );                  slap_queue_csn( &op2, &op->o_csn );
                 attr_merge_one( e, slap_schema.si_ad_entryCSN, &bv, NULL );  
                 slap_queue_csn( &op2, &bv );  
         }          }
   
         op2.o_bd->be_add( &op2, &rs2 );          op2.o_bd->be_add( &op2, &rs2 );
         slap_graduate_commit_csn( &op2 );  
         entry_free( e );          entry_free( e );
   
   done:
           ldap_pvt_thread_mutex_unlock( &li->li_log_mutex );
           return SLAP_CB_CONTINUE;
   }
   
   /* Since Bind success is sent by the frontend, it won't normally enter
    * the overlay response callback. Add another callback to make sure it
    * gets here.
    */
   static int
   accesslog_bind_resp( Operation *op, SlapReply *rs )
   {
           BackendDB *be, db;
           int rc;
           slap_callback *sc;
   
           be = op->o_bd;
           db = *be;
           op->o_bd = &db;
           db.bd_info = op->o_callback->sc_private;
           rc = accesslog_response( op, rs );
           op->o_bd = be;
           sc = op->o_callback;
           op->o_callback = sc->sc_next;
           op->o_tmpfree( sc, op->o_tmpmemctx );
           return rc;
   }
   
   static int
   accesslog_op_bind( Operation *op, SlapReply *rs )
   {
           slap_callback *sc;
   
           sc = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx );
           sc->sc_response = accesslog_bind_resp;
           sc->sc_private = op->o_bd->bd_info;
   
           if ( op->o_callback ) {
                   sc->sc_next = op->o_callback->sc_next;
                   op->o_callback->sc_next = sc;
           } else {
                   op->o_callback = sc;
           }
           return SLAP_CB_CONTINUE;
   }
   
   static int
   accesslog_op_mod( Operation *op, SlapReply *rs )
   {
           slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
           log_info *li = on->on_bi.bi_private;
   
           if ( li->li_ops & LOG_OP_WRITES ) {
                   /* FIXME: this needs to be a recursive mutex to allow
                    * overlays like refint to keep working.
                    */
                   ldap_pvt_thread_mutex_lock( &li->li_op_mutex );
           }
         return SLAP_CB_CONTINUE;          return SLAP_CB_CONTINUE;
 }  }
   
Line 999  static int accesslog_response(Operation Line 1107  static int accesslog_response(Operation
 static int  static int
 accesslog_unbind( Operation *op, SlapReply *rs )  accesslog_unbind( Operation *op, SlapReply *rs )
 {  {
         if ( op->o_conn->c_authz_backend == op->o_bd ) {          slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
                 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;          if ( op->o_conn->c_authz_backend == on->on_info->oi_origdb ) {
                 log_info *li = on->on_bi.bi_private;                  log_info *li = on->on_bi.bi_private;
                 Operation op2;                  Operation op2;
                   void *cids[SLAP_MAX_CIDS];
                 SlapReply rs2 = {REP_RESULT};                  SlapReply rs2 = {REP_RESULT};
                 Entry *e;                  Entry *e;
   
                 if ( !( li->li_ops & LOG_OP_UNBIND ))                  if ( !( li->li_ops & LOG_OP_UNBIND ))
                         return SLAP_CB_CONTINUE;                          return SLAP_CB_CONTINUE;
   
                 e = accesslog_entry( op, LOG_EN_UNBIND );                  e = accesslog_entry( op, LOG_EN_UNBIND, &op2 );
                 op2.o_hdr = op->o_hdr;                  op2.o_hdr = op->o_hdr;
                 op2.o_tag = LDAP_REQ_ADD;                  op2.o_tag = LDAP_REQ_ADD;
                 op2.o_time = op->o_time;  
                 op2.o_tincr = 0;  
                 op2.o_bd = li->li_db;                  op2.o_bd = li->li_db;
                 op2.o_dn = li->li_db->be_rootdn;                  op2.o_dn = li->li_db->be_rootdn;
                 op2.o_ndn = li->li_db->be_rootndn;                  op2.o_ndn = li->li_db->be_rootndn;
Line 1021  accesslog_unbind( Operation *op, SlapRep Line 1128  accesslog_unbind( Operation *op, SlapRep
                 op2.o_req_ndn = e->e_nname;                  op2.o_req_ndn = e->e_nname;
                 op2.ora_e = e;                  op2.ora_e = e;
                 op2.o_callback = &nullsc;                  op2.o_callback = &nullsc;
                   op2.o_controls = cids;
                   memset(cids, 0, sizeof( cids ));
                   memset(op2.o_ctrlflag, 0, sizeof( op2.o_ctrlflag ));
   
                 op2.o_bd->be_add( &op2, &rs2 );                  op2.o_bd->be_add( &op2, &rs2 );
                 entry_free( e );                  entry_free( e );
Line 1034  accesslog_abandon( Operation *op, SlapRe Line 1144  accesslog_abandon( Operation *op, SlapRe
         slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;          slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
         log_info *li = on->on_bi.bi_private;          log_info *li = on->on_bi.bi_private;
         Operation op2;          Operation op2;
           void *cids[SLAP_MAX_CIDS];
         SlapReply rs2 = {REP_RESULT};          SlapReply rs2 = {REP_RESULT};
         Entry *e;          Entry *e;
         char buf[64];          char buf[64];
Line 1042  accesslog_abandon( Operation *op, SlapRe Line 1153  accesslog_abandon( Operation *op, SlapRe
         if ( !op->o_time || !( li->li_ops & LOG_OP_ABANDON ))          if ( !op->o_time || !( li->li_ops & LOG_OP_ABANDON ))
                 return SLAP_CB_CONTINUE;                  return SLAP_CB_CONTINUE;
   
         e = accesslog_entry( op, LOG_EN_ABANDON );          e = accesslog_entry( op, LOG_EN_ABANDON, &op2 );
         bv.bv_val = buf;          bv.bv_val = buf;
         bv.bv_len = sprintf( buf, "%d", op->orn_msgid );          bv.bv_len = sprintf( buf, "%d", op->orn_msgid );
         attr_merge_one( e, ad_reqId, &bv, NULL );          attr_merge_one( e, ad_reqId, &bv, NULL );
   
         op2.o_hdr = op->o_hdr;          op2.o_hdr = op->o_hdr;
         op2.o_tag = LDAP_REQ_ADD;          op2.o_tag = LDAP_REQ_ADD;
         op2.o_time = op->o_time;  
         op2.o_tincr = 0;  
         op2.o_bd = li->li_db;          op2.o_bd = li->li_db;
         op2.o_dn = li->li_db->be_rootdn;          op2.o_dn = li->li_db->be_rootdn;
         op2.o_ndn = li->li_db->be_rootndn;          op2.o_ndn = li->li_db->be_rootndn;
Line 1058  accesslog_abandon( Operation *op, SlapRe Line 1167  accesslog_abandon( Operation *op, SlapRe
         op2.o_req_ndn = e->e_nname;          op2.o_req_ndn = e->e_nname;
         op2.ora_e = e;          op2.ora_e = e;
         op2.o_callback = &nullsc;          op2.o_callback = &nullsc;
           op2.o_controls = cids;
           memset(cids, 0, sizeof( cids ));
           memset(op2.o_ctrlflag, 0, sizeof( op2.o_ctrlflag ));
   
         op2.o_bd->be_add( &op2, &rs2 );          op2.o_bd->be_add( &op2, &rs2 );
         entry_free( e );          entry_free( e );
Line 1076  accesslog_db_init( Line 1188  accesslog_db_init(
         log_info *li = ch_calloc(1, sizeof(log_info));          log_info *li = ch_calloc(1, sizeof(log_info));
   
         on->on_bi.bi_private = li;          on->on_bi.bi_private = li;
           ldap_pvt_thread_mutex_init( &li->li_op_mutex );
           ldap_pvt_thread_mutex_init( &li->li_log_mutex );
         return 0;          return 0;
 }  }
   
Line 1087  accesslog_db_destroy( Line 1201  accesslog_db_destroy(
         slap_overinst *on = (slap_overinst *)be->bd_info;          slap_overinst *on = (slap_overinst *)be->bd_info;
         log_info *li = on->on_bi.bi_private;          log_info *li = on->on_bi.bi_private;
                   
           ldap_pvt_thread_mutex_destroy( &li->li_log_mutex );
           ldap_pvt_thread_mutex_destroy( &li->li_op_mutex );
         free( li );          free( li );
         return LDAP_SUCCESS;          return LDAP_SUCCESS;
 }  }
Line 1099  int accesslog_init() Line 1215  int accesslog_init()
         accesslog.on_bi.bi_db_init = accesslog_db_init;          accesslog.on_bi.bi_db_init = accesslog_db_init;
         accesslog.on_bi.bi_db_destroy = accesslog_db_destroy;          accesslog.on_bi.bi_db_destroy = accesslog_db_destroy;
   
           accesslog.on_bi.bi_op_add = accesslog_op_mod;
           accesslog.on_bi.bi_op_bind = accesslog_op_bind;
           accesslog.on_bi.bi_op_delete = accesslog_op_mod;
           accesslog.on_bi.bi_op_modify = accesslog_op_mod;
           accesslog.on_bi.bi_op_modrdn = accesslog_op_mod;
         accesslog.on_bi.bi_op_unbind = accesslog_unbind;          accesslog.on_bi.bi_op_unbind = accesslog_unbind;
         accesslog.on_bi.bi_op_abandon = accesslog_abandon;          accesslog.on_bi.bi_op_abandon = accesslog_abandon;
         accesslog.on_response = accesslog_response;          accesslog.on_response = accesslog_response;

Removed from v.1.2.2.8  
changed lines
  Added in v.1.2.2.9


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org