From fd3832d269b19a7fe6094a6de8da8d743b62c540 Mon Sep 17 00:00:00 2001
From: William Brown <firstyear@redhat.com>
Date: Fri, 19 Aug 2016 12:49:17 +1000
Subject: [PATCH] Ticket 48958 - Audit fail log doesn't work if audit log
 disabled.

Bug Description:  Due to a configuration interpretation issue, when audit was
not enabled, but auditfail was with no log defined, the fail log should write to
the audit log location on failed events, but audit events should not be written.
This did not work.

Fix Description:  This was because when we wrote to the audit file in the
abscence of the auditfail log, the audit enabled state was checked. This adds a
check to determine what the source event was from, and to check the correct log
enabled state during the event processing.

https://fedorahosted.org/389/ticket/48958

Author: wibrown

Review by: ???
---
 ldap/servers/slapd/auditlog.c   | 15 +++++----
 ldap/servers/slapd/log.c        | 71 ++++++++++++++++++++++++-----------------
 ldap/servers/slapd/proto-slap.h |  4 +--
 3 files changed, 53 insertions(+), 37 deletions(-)

diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c
index 0f4cc94..ec7111b 100644
--- a/ldap/servers/slapd/auditlog.c
+++ b/ldap/servers/slapd/auditlog.c
@@ -33,7 +33,7 @@ static int audit_hide_unhashed_pw = 1;
 static int auditfail_hide_unhashed_pw = 1;
 
 /* Forward Declarations */
-static void write_audit_file(int logtype, int optype, const char *dn, void *change, int flag, time_t curtime, int rc );
+static void write_audit_file(int logtype, int optype, const char *dn, void *change, int flag, time_t curtime, int rc, int sourcelog );
 
 static const char *modrdn_changes[4];
 
@@ -98,7 +98,7 @@ write_audit_log_entry( Slapi_PBlock *pb )
     curtime = current_time();
     /* log the raw, unnormalized DN */
     dn = slapi_sdn_get_udn(sdn);
-    write_audit_file(SLAPD_AUDIT_LOG, operation_get_type(op), dn, change, flag, curtime, LDAP_SUCCESS);
+    write_audit_file(SLAPD_AUDIT_LOG, operation_get_type(op), dn, change, flag, curtime, LDAP_SUCCESS, SLAPD_AUDIT_LOG);
 }
 
 void
@@ -169,10 +169,10 @@ write_auditfail_log_entry( Slapi_PBlock *pb )
     auditfail_config = config_get_auditfaillog();
     if (auditfail_config == NULL || strlen(auditfail_config) == 0) {
         /* If no auditfail log write to audit log */
-        write_audit_file(SLAPD_AUDIT_LOG, operation_get_type(op), dn, change, flag, curtime, pbrc);
+        write_audit_file(SLAPD_AUDIT_LOG, operation_get_type(op), dn, change, flag, curtime, pbrc, SLAPD_AUDITFAIL_LOG);
     } else {
         /* If we have our own auditfail log path */
-        write_audit_file(SLAPD_AUDITFAIL_LOG, operation_get_type(op), dn, change, flag, curtime, pbrc);
+        write_audit_file(SLAPD_AUDITFAIL_LOG, operation_get_type(op), dn, change, flag, curtime, pbrc, SLAPD_AUDITFAIL_LOG);
     }
     slapi_ch_free_string(&auditfail_config);
 }
@@ -181,6 +181,7 @@ write_auditfail_log_entry( Slapi_PBlock *pb )
 /*
  * Function: write_audit_file
  * Arguments: 
+ *            logtype - Destination where the message will go.
  *            optype - type of LDAP operation being logged
  *            dn     - distinguished name of entry being changed
  *            change - pointer to the actual change operation
@@ -188,6 +189,7 @@ write_auditfail_log_entry( Slapi_PBlock *pb )
  *            flag   - only used by modrdn operations - value of deleteoldrdn flag
  *            curtime - the current time
  *            rc     - The ldap result code. Used in conjunction with auditfail
+ *            sourcelog - The source of the message (audit or auditfail)
  * Returns: nothing
  */
 static void
@@ -198,7 +200,8 @@ write_audit_file(
     void        *change,
     int         flag,
     time_t      curtime,
-    int         rc
+    int         rc,
+    int         sourcelog
 )
 {
     LDAPMod **mods;
@@ -359,7 +362,7 @@ write_audit_file(
     switch (logtype)
     {
     case SLAPD_AUDIT_LOG:
-        slapd_log_audit (l->ls_buf, l->ls_len);
+        slapd_log_audit (l->ls_buf, l->ls_len, sourcelog);
         break;
     case SLAPD_AUDITFAIL_LOG:
         slapd_log_auditfail (l->ls_buf, l->ls_len);
diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c
index a16c395..ae8b5f8 100644
--- a/ldap/servers/slapd/log.c
+++ b/ldap/servers/slapd/log.c
@@ -1962,14 +1962,26 @@ auditfail_log_openf( char *pathname, int locked)
 
 int
 slapd_log_audit (
-	char	*buffer,
-	int	buf_len)
+    char *buffer,
+    int buf_len,
+    int sourcelog)
 {
     /* We use this to route audit log entries to where they need to go */
     int retval = LDAP_SUCCESS;
     int lbackend = loginfo.log_backend; /* We copy this to make these next checks atomic */
+
+    int state = 0;
+    if (sourcelog == SLAPD_AUDIT_LOG) {
+        state = loginfo.log_audit_state;
+    } else if (sourcelog == SLAPD_AUDITFAIL_LOG ) {
+        state = loginfo.log_auditfail_state;
+    } else {
+        /* How did we even get here! */
+        return 1;
+    }
+
     if (lbackend & LOGGING_BACKEND_INTERNAL) {
-        retval = slapd_log_audit_internal(buffer, buf_len);
+        retval = slapd_log_audit_internal(buffer, buf_len, state);
     }
 
     if (retval != LDAP_SUCCESS) {
@@ -1989,33 +2001,34 @@ slapd_log_audit (
 
 int
 slapd_log_audit_internal (
-	char	*buffer,
-	int	buf_len)
+    char    *buffer,
+    int buf_len,
+    int state)
 {
-	if ( (loginfo.log_audit_state & LOGGING_ENABLED) && (loginfo.log_audit_file != NULL) ){
-		LOG_AUDIT_LOCK_WRITE( );
-		if (log__needrotation(loginfo.log_audit_fdes,
-					SLAPD_AUDIT_LOG) == LOG_ROTATE) {
-    		if (log__open_auditlogfile(LOGFILE_NEW, 1) != LOG_SUCCESS) {
-	    		LDAPDebug(LDAP_DEBUG_ANY,
-    				"LOGINFO: Unable to open audit file:%s\n",
-	    			loginfo.log_audit_file,0,0);
-    			LOG_AUDIT_UNLOCK_WRITE();
-	    		return 0;
-			}
-			while (loginfo.log_audit_rotationsyncclock <= loginfo.log_audit_ctime) {
-				loginfo.log_audit_rotationsyncclock += PR_ABS(loginfo.log_audit_rotationtime_secs);
-			}
-		}
-		if (loginfo.log_audit_state & LOGGING_NEED_TITLE) {
-			log_write_title( loginfo.log_audit_fdes);
-			loginfo.log_audit_state &= ~LOGGING_NEED_TITLE;
-		}
-	    LOG_WRITE_NOW_NO_ERR(loginfo.log_audit_fdes, buffer, buf_len, 0);
-   		LOG_AUDIT_UNLOCK_WRITE();
-	    return 0;
-	}
-	return 0;
+    if ( (state & LOGGING_ENABLED) && (loginfo.log_audit_file != NULL) ){
+        LOG_AUDIT_LOCK_WRITE( );
+        if (log__needrotation(loginfo.log_audit_fdes,
+                    SLAPD_AUDIT_LOG) == LOG_ROTATE) {
+            if (log__open_auditlogfile(LOGFILE_NEW, 1) != LOG_SUCCESS) {
+                LDAPDebug(LDAP_DEBUG_ANY,
+                    "LOGINFO: Unable to open audit file:%s\n",
+                    loginfo.log_audit_file,0,0);
+                LOG_AUDIT_UNLOCK_WRITE();
+                return 0;
+            }
+            while (loginfo.log_audit_rotationsyncclock <= loginfo.log_audit_ctime) {
+                loginfo.log_audit_rotationsyncclock += PR_ABS(loginfo.log_audit_rotationtime_secs);
+            }
+        }
+        if (state & LOGGING_NEED_TITLE) {
+            log_write_title( loginfo.log_audit_fdes);
+            state &= ~LOGGING_NEED_TITLE;
+        }
+        LOG_WRITE_NOW_NO_ERR(loginfo.log_audit_fdes, buffer, buf_len, 0);
+        LOG_AUDIT_UNLOCK_WRITE();
+        return 0;
+    }
+    return 0;
 }
 /******************************************************************************
 * write in the audit fail log
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 6bc1065..1f37010 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -766,8 +766,8 @@ int slapi_log_access( int level, char *fmt, ... )
 #else
         ;
 #endif
-int slapd_log_audit(char *buffer, int buf_len);
-int slapd_log_audit_internal(char *buffer, int buf_len);
+int slapd_log_audit(char *buffer, int buf_len, int sourcelog);
+int slapd_log_audit_internal(char *buffer, int buf_len, int state);
 int slapd_log_auditfail(char *buffer, int buf_len);
 int slapd_log_auditfail_internal(char *buffer, int buf_len);
 void log_access_flush();
-- 
1.8.3.1

