6. Auditing Files and Directories
It's possible to audit many user (or other principal)
activities by placing an audit directly on the user. However, the
number of event log entries generated by such an action can be
overwhelming. In many cases, you end up with too much information to
process successfully. An alternative is to place an audit on the
resource. This form of audit is targeted and generates just the messages
you need. Of course, if you really do want to monitor all a user's
activities, you still need to place an audit on the user. The following
sections show how to place an audit on a file, but you can easily extend
the techniques to work with other resource types.
6.1. Configuring the Audit Activity Example
This example begins with a Windows Forms application that has a single button, btnAudit,
which the user clicks to add or remove auditing. Because this
application deals with auditing. You also need to add the following using statements:
using System.Security.AccessControl;
using System.Security.Principal;
using System.IO;
6.2. Writing the Audit Activity Code
It monitors the state of auditing
on the file. If the file isn't audited, then the code adds auditing to
it; otherwise, the code removes auditing from the file. The basic
process is the same as adding an access rule to a file, except that you
work with the SACL rather than the DACL. Listing 7 shows the code required for this example.
Example 7. Performing an audit of actions on a file or directory
private void btnAudit_Click(object sender, EventArgs e)
{
// Create a file security object for the target file.
FileSecurity FS = File.GetAccessControl(
Application.StartupPath + @"\Temp.TXT",
AccessControlSections.Audit);
// Create a new rule.
FileSystemAuditRule Rule = new FileSystemAuditRule(
new NTAccount(@"BUILTIN\Users"),
FileSystemRights.Write,
AuditFlags.Failure);
// Obtain a list of the existing rules.
AuthorizationRuleCollection AuditRules =
FS.GetAuditRules(true, true,
typeof(NTAccount));
// Check for the existence of the rule in the collection.
Boolean FoundIt = false;
foreach (FileSystemAuditRule AR in AuditRules)
// Look for the rule.
if ((AR.IdentityReference == Rule.IdentityReference) &&
(AR.FileSystemRights.HasFlag(FileSystemRights.Write)) &&
(AR.AuditFlags.HasFlag(AuditFlags.Failure)))
{
// Set FoundIt appropriately.
FoundIt = true;
// Exit the loop.
break;
}
// Add or remove the rule as appropriate.
if (FoundIt)
// Remove the rule from the file security object.
FS.RemoveAuditRule(Rule);
else
// Add the rule to the file security object.
FS.AddAuditRule(Rule);
// Save the rule to the file.
File.SetAccessControl(
Application.StartupPath + @"\Temp.TXT", FS);
// Display a success message.
MessageBox.Show("Change Succeeded!");
}
|
The code begins by creating a FileSecurity object, FS, using Temp.TXT. Notice that you must include the AccessControlSections.Audit argument in this case. The default is to provide a FileSecurity object for the DACL, so you must tell the system that you actually want to work with the SACL instead.
The next step is to create a FileSystemAuditRule, Rule, that provides the user account, right to monitor, and type of monitoring to perform as input. There are 23 different FileSystemRights values you can use to define the rights you want monitored, and you can "or" the values together as needed (such as FileSystemRights.Write | FileSystemRights.Read for both read and write access). The audit flags are AuditFlags.Failure and AuditFlags.Success. If you want to monitor both success and failure, you "or" the flags together (AuditFlags.Failure | AuditFlags.Success).
At this point, the code can begin checking for the presence of a particular auditing rule. It creates an AuthorizationRuleCollection object, AuditRules, which includes both explicit and inherited audit rules of type NTAccount. The code uses a for loop to review each of the FileSystemAuditRule entries, AR, in turn. To successfully find a particular rule, you must check the IdentityReference, FileSystemRights, and AuditFlags properties. The HasFlag() method makes it easy to find particular flags in the list. Once the code finds the entry of interest, it sets FoundIt to true and breaks out of the loop.
One of two events can happen at this point. The code can call RemoveAuditRule() to remove the rule from the list or AddAuditRule() to add the rule to the list based on the value of FoundIt. The code then calls SetAccessControl() to set the new rules in place.
Viewing the results is a little more complicated than viewing access rights. Use these steps to see the audit rights:
Right-click Temp.TXT and choose Properties from the Context menu.
Click Advanced to display the Advanced Security Settings for Temp.TXT dialog box shown in Figure 15.
Select the Auditing tab as shown in Figure 15. Notice that even when using this editor, you must rely on privilege elevation to see the entries.
Click
Continue. You'll see a second Advanced Security Settings for Temp.TXT
dialog box open with just an Auditing tab, as shown in Figure 16. This time, you can see the audit rule the application created.