Philip Hendry's Blog

March 23, 2011

Configuring Event Log Permission for Asp.net applications

Filed under: ASP.NET, Security — philiphendry @ 2:40 pm

I’ve been having some problems with writing to a custom event log as well as the standard ‘Application’ event log where it failed with the following error :

    Stack Trace: 
    
    
    [Win32Exception (0x80004005): Access is denied]
    
    [InvalidOperationException: Cannot open log for source 'Application'. You may not have write access.]
    System.Diagnostics.EventLog.OpenForWrite(String currentMachineName) +1008783
    System.Diagnostics.EventLog.InternalWriteEvent(UInt32 eventID, UInt16 category, EventLogEntryType type, String[] strings, Byte[] rawData, String currentMachineName) +216
    System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData) +264
    System.Diagnostics.EventLog.WriteEntry(String source, String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData) +87
    System.Diagnostics.EventLog.WriteEntry(String source, String message, EventLogEntryType type) +14
    ASP.test_testeventlogaccess_aspx.WriteToApplication(Object sender, EventArgs e) in c:\Inetpub\wwwroot\connect\Test\TestEventLogAccess.aspx:20
    System.Web.UI.WebControls.Button.OnClick(EventArgs e) +111
    System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +110
    System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
    System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
    System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565

What made this harder to figure was it worked in one environment but not another! The difference was impersonation was turned on in the web.config for the failing web site :


  <system.web>
    <identity impersonate="true" />
  </system.web>

This meant that the user being used to access the event log was not the AppPool identity but rather the ASP.NET IUSR_ identity (which has not been overridden with the optional username/password attributes above in the config above.)

Microsoft has a knowledge base article describing how to configure event log permissions but there were two extra steps I had to perform before I could add the IUSR identity to the event log permissions :

Fetching the SID for an account

The SDDL string that needs to be added according to the knowledge base article referenced above requires the SID for the IUSR account. There are a couple of ways to do this listed below. Either script block should be saved to a .vbs file and run as a parameter to cscript.exe from a command line :

    strComputer = "."
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set objAccount = objWMIService.Get("Win32_UserAccount.Name='IUSR_<COMPUTER NAME>',Domain='<COMPUTER NAME>'")
    Wscript.Echo objAccount.SID
    
    
    On Error Resume Next
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * from Win32_UserAccount",,48)
    For Each objItem in colItems
        Wscript.Echo "AccountType: " & objItem.AccountType
        Wscript.Echo "Caption: " & objItem.Caption
        Wscript.Echo "Description: " & objItem.Description
        Wscript.Echo "Disabled: " & objItem.Disabled
        Wscript.Echo "Domain: " & objItem.Domain
        Wscript.Echo "FullName: " & objItem.FullName
        Wscript.Echo "InstallDate: " & objItem.InstallDate
        Wscript.Echo "Lockout: " & objItem.Lockout
        Wscript.Echo "Name: " & objItem.Name
        Wscript.Echo "PasswordChangeable: " & objItem.PasswordChangeable
        Wscript.Echo "PasswordExpires: " & objItem.PasswordExpires
        Wscript.Echo "PasswordRequired: " & objItem.PasswordRequired
        Wscript.Echo "SID: " & objItem.SID
        Wscript.Echo "SIDType: " & objItem.SIDType
        Wscript.Echo "Status: " & objItem.Status
    Next

Remove the IUSR Identity from the Guest Users Group

The last modification which is not mentioned in the knowledge base article is that the Guest Users group is already explicitly denied access to the event log (at least on my Windows Server 2003 machine) and therefore adding the SID for this account will not have an account. To solve this I removed the IUSR account from the Guest Users group and everything worked.

Debugging

As an aside to be able to test and debug this on both a production and test server I created an .aspx file with no code-behind with the following code :

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Diagnostics"%>
    
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Test Event Log Access</title>
        
        <script runat="server">
        
        protected void WriteToMyEventLog(object sender, EventArgs e)
        {
            EventLog.WriteEntry("MyEventLog", "This is a test", EventLogEntryType.Error);
        }
    
        protected void WriteToApplication(object sender, EventArgs e)
        {
            EventLog.WriteEntry("Application", "This is a test", EventLogEntryType.Error);
        }        
        </script>
        
    </head>
    <body>
        <form id="form" runat="server">
        <div>
            <asp:Button runat="server" ID="btnWriteToMyEventLog" Text="Write to My Event Log" OnClick="WriteToMyEventLog" />
            <asp:Button runat="server" ID="btnWriteToApplication" Text="Write to Application" OnClick="WriteToApplication" />
        </div>
        </form>
    </body>
    </html>

About these ads

2 Comments »

  1. vbscript files are so yesterday! Here’s a link to a ScriptingGuy blog article that shows how to do the same thing using a PowerShell script:

    http://blogs.technet.com/b/heyscriptingguy/archive/2010/10/11/use-wmi-and-powershell-to-get-a-user-s-sid.aspx

    Comment by Ian — March 29, 2011 @ 9:29 pm

  2. I do like Powershell… I’ve even given a training course before now but if it’s not on the server it’s so much easier to ‘get the job done’ with my old favourite batch files, oh, and yucky vbscript of course.

    Comment by philiphendry — March 30, 2011 @ 8:53 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Shocking Blue Green. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: