An Avanade Blogging Community

Welcome to An Avanade Blogging Community Sign in | Join | Help
in Search

John Reynolds' Tech Blog

Clearing the Event Log while running under a service account

I ran into a situation recently where I had a Windows service running under a domain service account, e.g., MyDomain\SvcUser. As part of its operation, the service needed to clear the Event Log after reading its contents. By default, non-administrative accounts cannot clear an event log.
Granting 'clear' access on an event log to a service account is not as simple as it might sound.
After reading this post by Rory McCaw, I learned that the permissions are controlled by a custom security descriptor stored in the registry.
The key is stored here:
MACHINE\System\CurrentControlSet\Services\EventLog\[CustomLognName]\CustomSD

This applies to Window Server 2003, apparently the security on the event log has changed from the prior version.

In the CustomSD key, you will find some long string like this:
O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)
(from Rory's blog)

The first part is the 'Owner' ACL [ O:BA ], which tells you the Owner is the Builtin Administrators
The next part is the 'Group' ACL [G:SY], the primary group is the Local System account
The last, long group is the Discretionary ACL (or DACL) D:(...)(...) which grants discretionary access on a user-by-user basis.
Each DACL entry is in the form (A;;0x7;;;S-1-5-21-467819145....)
which is Allow or Deny; then the permissions (for the event log, 0x7 is full control); followed by the SID of the user to be granted/denied the permission.

To put this information to use, I have created a command line utility that allows one to easily update the permissions on an event log. I will post some code here when I have time to rewrite it. Here are some of the highlights:

Using the System.Security.Principal namespace

// Get the account SID
NTAccount ntAccount = new NTAccount("MyDomain", "MyAccount");
SecurityIdentifier sid = ( SecurityIdentifier ) ntAccount.Translate( typeof( SecurityIdentifier ) );

//Open the Security Descriptor from the registry
// using the Microsoft.Win32 namespace
string eventLogName = "MyEventLogName";
      string sddl = Registry.GetValue( @"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\" + eventLogName, "CustomSD", string.Empty ).ToString();

// Omitted: Code to concatenate together the SID and the permission level to update the security descriptor

//Save back the updated Security descriptor to the registry
Registry.SetValue( @"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\" + eventLogName, "CustomSD", updatedSDDL );

So now your service accounts can have full control over an event log without having administrative rights on the computer.

My unanswered question is this: what class will allow me to manipulate the security descriptor directly? When I attempt to instantiate one of the security descriptor classes like this:

CommonSecurityDescriptor sd = new CommonSecurityDescriptor( false, false, eventLogSDDL );
// omitted code to add ACEs to DACL
sd.GetSddlForm( AccessControlSections.All );

Trying to convert the security descriptor back to a SDDL string results in some extra stuff in the string:
Input:
O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0007;;;SY)(A;;0x7;;;BA)(A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)
Outputs:
O:BAG:SYD:(D;;CCDCLCSDRCWDWO;;;AN)(D;;CCDCLCSDRCWDWO;;;BG)(A;;CCDC;;;S-1-5-3)(A;;CCDC;;;IU)(A;;CCDC;;;SU)(A;;CCDCLCSDRCWDWO;;;SY)(A;;CCDCLC;;;BA)(A;;CCDCLC;;;SO)

Does anyone know how to manipulate the SDDL correctly via .Net?
Published Wednesday, July 11, 2007 4:04 PM by johnrey

Comments

No Comments
Anonymous comments are disabled

This Blog

Post Calendar

<July 2007>
SuMoTuWeThFrSa
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

Post Categories

Syndication