Skip to content

Commit d7bfb60

Browse files
committed
per item configuration change auditing
1 parent 7ceb429 commit d7bfb60

File tree

4 files changed

+67
-75
lines changed

4 files changed

+67
-75
lines changed

server/src/main/java/password/pwm/PwmApplication.java

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -315,32 +315,7 @@ private void postInitTasks( )
315315
{
316316
LOGGER.error( "error outputting log to debug: " + e.getMessage() );
317317
}
318-
319-
// detect if config has been modified since previous startup
320-
try
321-
{
322-
final String previousHash = readAppAttribute( AppAttribute.CONFIG_HASH, String.class );
323-
final String currentHash = pwmEnvironment.getConfig().configurationHash( this.getSecureService() );
324-
if ( previousHash == null || !previousHash.equals( currentHash ) )
325-
{
326-
writeAppAttribute( AppAttribute.CONFIG_HASH, currentHash );
327-
LOGGER.warn( "configuration checksum does not match previously seen checksum, configuration has been modified since last startup" );
328-
if ( this.getAuditManager() != null )
329-
{
330-
final String modifyMessage = "configuration was modified directly (not using ConfigEditor UI)";
331-
this.getAuditManager().submit( new AuditRecordFactory( this ).createUserAuditRecord(
332-
AuditEvent.MODIFY_CONFIGURATION,
333-
null,
334-
null,
335-
modifyMessage
336-
) );
337-
}
338-
}
339-
}
340-
catch ( Exception e )
341-
{
342-
LOGGER.debug( () -> "unable to detect if configuration has been modified since previous startup: " + e.getMessage() );
343-
}
318+
344319

345320
if ( this.getConfig() != null )
346321
{

server/src/main/java/password/pwm/config/stored/ConfigurationReader.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,15 @@
2525
import password.pwm.PwmApplicationMode;
2626
import password.pwm.PwmConstants;
2727
import password.pwm.bean.SessionLabel;
28+
import password.pwm.bean.UserIdentity;
2829
import password.pwm.config.Configuration;
30+
import password.pwm.config.StoredValue;
2931
import password.pwm.error.ErrorInformation;
3032
import password.pwm.error.PwmError;
3133
import password.pwm.error.PwmOperationalException;
3234
import password.pwm.error.PwmUnrecoverableException;
35+
import password.pwm.svc.event.AuditEvent;
36+
import password.pwm.svc.event.AuditRecordFactory;
3337
import password.pwm.util.java.FileSystemUtility;
3438
import password.pwm.util.java.JavaHelper;
3539
import password.pwm.util.java.StringUtil;
@@ -46,6 +50,7 @@
4650
import java.time.Instant;
4751
import java.util.List;
4852
import java.util.Optional;
53+
import java.util.Set;
4954

5055
/**
5156
* Read the PWM configuration.
@@ -263,6 +268,11 @@ public void saveConfiguration(
263268
}
264269
}
265270

271+
if ( pwmApplication != null && pwmApplication.getAuditManager() != null )
272+
{
273+
auditModifiedSettings( pwmApplication, storedConfiguration, sessionLabel );
274+
}
275+
266276
try
267277
{
268278
outputConfigurationFile( storedConfiguration, pwmApplication, sessionLabel, backupRotations, backupDirectory );
@@ -273,6 +283,34 @@ public void saveConfiguration(
273283
}
274284
}
275285

286+
private static void auditModifiedSettings( final PwmApplication pwmApplication, final StoredConfiguration newConfig, final SessionLabel sessionLabel )
287+
throws PwmUnrecoverableException
288+
{
289+
final Set<StoredConfigItemKey> changedKeys = StoredConfigurationUtil.changedValues( newConfig, pwmApplication.getConfig().getStoredConfiguration() );
290+
291+
for ( final StoredConfigItemKey key : changedKeys )
292+
{
293+
if ( key.getRecordType() == StoredConfigItemKey.RecordType.SETTING
294+
|| key.getRecordType() == StoredConfigItemKey.RecordType.LOCALE_BUNDLE )
295+
{
296+
final Optional<StoredValue> storedValue = newConfig.readStoredValue( key );
297+
if ( storedValue.isPresent() )
298+
{
299+
final Optional<ValueMetaData> valueMetaData = newConfig.readMetaData( key );
300+
final UserIdentity userIdentity = valueMetaData.map( ValueMetaData::getUserIdentity ).orElse( null );
301+
final String modifyMessage = "configuration record '" + key.getLabel( PwmConstants.DEFAULT_LOCALE )
302+
+ "' has been modified, new value: " + storedValue.get().toDebugString( PwmConstants.DEFAULT_LOCALE );
303+
pwmApplication.getAuditManager().submit( new AuditRecordFactory( pwmApplication ).createUserAuditRecord(
304+
AuditEvent.MODIFY_CONFIGURATION,
305+
userIdentity,
306+
sessionLabel,
307+
modifyMessage
308+
) );
309+
}
310+
}
311+
}
312+
}
313+
276314
private void outputConfigurationFile(
277315
final StoredConfiguration storedConfiguration,
278316
final PwmApplication pwmApplication,

server/src/main/java/password/pwm/http/servlet/configmanager/ConfigManagerServlet.java

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import password.pwm.PwmConstants;
3030
import password.pwm.config.stored.ConfigurationProperty;
3131
import password.pwm.config.stored.ConfigurationReader;
32-
import password.pwm.config.stored.StoredConfigItemKey;
3332
import password.pwm.config.stored.StoredConfiguration;
3433
import password.pwm.config.stored.StoredConfigurationFactory;
3534
import password.pwm.config.stored.StoredConfigurationModifier;
@@ -56,10 +55,6 @@
5655
import password.pwm.i18n.Admin;
5756
import password.pwm.i18n.Config;
5857
import password.pwm.i18n.Display;
59-
import password.pwm.svc.PwmService;
60-
import password.pwm.svc.event.AuditEvent;
61-
import password.pwm.svc.event.AuditRecord;
62-
import password.pwm.svc.event.AuditRecordFactory;
6358
import password.pwm.util.LDAPPermissionCalculator;
6459
import password.pwm.util.i18n.LocaleHelper;
6560
import password.pwm.util.java.JavaHelper;
@@ -77,7 +72,6 @@
7772
import java.util.LinkedHashMap;
7873
import java.util.List;
7974
import java.util.Map;
80-
import java.util.Set;
8175
import java.util.zip.ZipOutputStream;
8276

8377
@WebServlet(
@@ -326,26 +320,6 @@ public static void saveConfiguration(
326320
pwmRequest.getSessionLabel()
327321
);
328322

329-
final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
330-
if ( pwmApplication.getAuditManager() != null && pwmApplication.getAuditManager().status() == PwmService.STATUS.OPEN )
331-
{
332-
final Set<StoredConfigItemKey> configurationDifferential = StoredConfigurationUtil.changedValues(
333-
pwmApplication.getConfig().getStoredConfiguration(),
334-
storedConfiguration );
335-
final String modifyMessage = "Configuration Changes: " + StoredConfigurationUtil.changeLogAsDebugString(
336-
storedConfiguration,
337-
configurationDifferential,
338-
PwmConstants.DEFAULT_LOCALE
339-
);
340-
final AuditRecord auditRecord = new AuditRecordFactory( pwmApplication ).createUserAuditRecord(
341-
AuditEvent.MODIFY_CONFIGURATION,
342-
pwmRequest.getUserInfoIfLoggedIn(),
343-
pwmRequest.getSessionLabel(),
344-
modifyMessage
345-
);
346-
pwmApplication.getAuditManager().submit( auditRecord );
347-
}
348-
349323
contextManager.requestPwmApplicationRestart();
350324
}
351325
catch ( Exception e )

server/src/main/java/password/pwm/util/localdb/LocalDB.java

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
package password.pwm.util.localdb;
2222

2323
import password.pwm.util.java.ClosableIterator;
24+
import password.pwm.util.java.JavaHelper;
2425

2526
import java.io.File;
2627
import java.io.Serializable;
@@ -116,35 +117,39 @@ enum DB
116117
/**
117118
* Used for various pwm operational data.
118119
*/
119-
PWM_META( true ),
120-
SHAREDHISTORY_META( true ),
121-
SHAREDHISTORY_WORDS( true ),
120+
PWM_META( Flag.Backup ),
121+
SHAREDHISTORY_META( Flag.Backup ),
122+
SHAREDHISTORY_WORDS( Flag.Backup ),
122123
// WORDLIST_META(true), // @deprecated
123-
WORDLIST_WORDS( true ),
124+
WORDLIST_WORDS( Flag.Backup ),
124125
// SEEDLIST_META(true), // @deprecated
125-
SEEDLIST_WORDS( true ),
126-
PWM_STATS( true ),
127-
EVENTLOG_EVENTS( true ),
128-
EMAIL_QUEUE( true ),
129-
SMS_QUEUE( true ),
130-
RESPONSE_STORAGE( true ),
131-
OTP_SECRET( true ),
132-
TOKENS( true ),
133-
INTRUDER( true ),
134-
AUDIT_QUEUE( true ),
135-
AUDIT_EVENTS( true ),
136-
USER_CACHE( true ),
137-
TEMP( false ),
138-
SYSLOG_QUEUE( true ),
139-
CACHE( false ),
140-
141-
REPORT_QUEUE( false ),;
126+
SEEDLIST_WORDS( Flag.Backup ),
127+
PWM_STATS( Flag.Backup ),
128+
EVENTLOG_EVENTS( Flag.Backup ),
129+
EMAIL_QUEUE( Flag.Backup ),
130+
SMS_QUEUE( Flag.Backup ),
131+
RESPONSE_STORAGE( Flag.Backup ),
132+
OTP_SECRET( Flag.Backup ),
133+
TOKENS( Flag.Backup ),
134+
INTRUDER( Flag.Backup ),
135+
AUDIT_QUEUE( Flag.Backup ),
136+
AUDIT_EVENTS( Flag.Backup ),
137+
USER_CACHE( Flag.Backup ),
138+
TEMP( ),
139+
SYSLOG_QUEUE( Flag.Backup ),
140+
CACHE( ),
141+
REPORT_QUEUE( ),;
142142

143143
private final boolean backup;
144144

145-
DB( final boolean backup )
145+
private enum Flag
146146
{
147-
this.backup = backup;
147+
Backup,
148+
}
149+
150+
DB( final Flag... flag )
151+
{
152+
this.backup = JavaHelper.enumArrayContainsValue( flag, Flag.Backup );
148153
}
149154

150155
public boolean isBackup( )

0 commit comments

Comments
 (0)