Security- access to Event Viewer

P

Patrick

I have the following code, which regardless which works fine and logs to the
EventViewer regardless of whether
<processModel/> section of machine.config is set to username="SYSTEM" or
"machine"

---Start of test.aspx----
<%@ Page language="C#" AutoEventWireup="false" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title> test</title>
</HEAD>

<body>
<%

try
{
System.Diagnostics.EventLog objEventLog;

if (!System.Diagnostics.EventLog.SourceExists("TESTSOURCE"))
{

System.Diagnostics.EventLog.CreateEventSource("TESTSOURCE","Application");
}

objEventLog = new System.Diagnostics.EventLog();
objEventLog.Source = "TESTSOURCE";


if ( objEventLog.Log.ToUpper() != "APPLICATION" )
{
System.Console.WriteLine("Some other application is
using the source!");
return;
}

objEventLog.WriteEntry("Message",
System.Diagnostics.EventLogEntryType.Error);

}
catch (Exception e)
{
%>
<%=e%>

<%
} //end try
%>
</body>
</HTML>
----End of test.aspx----
However, if I have some very similar code in a Logging.cs file as follows:

--Start of logging.cs--
using System;
using System.Diagnostics;

namespace website.classes
{




public class Logging
{
private const string EVENT_SOURCE = "YJBWEBSITE";
private const string EVENT_LOG = "Applicaiton";



public Logging()
{
//Default constructor
}


public static void LogEventViewer(string
strMessage,EventLogEntryType objLogEntryType)
{
try
{
EventLog objEventLog;

if (!EventLog.SourceExists(EVENT_SOURCE))
{
EventLog.CreateEventSource(EVENT_SOURCE,EVENT_LOG);
}

objEventLog = new EventLog();
objEventLog.Source = EVENT_SOURCE;


if ( objEventLog.Log.ToUpper() != EVENT_LOG.ToUpper() )
{
System.Console.WriteLine("Some other application is
using the source!");
return;
}

objEventLog.WriteEntry(strMessage,objLogEntryType);

}
catch (Exception e)
{

System.Console.WriteLine(e);
return;
} //end try

} //end LogEventViewer


public static void LogError(string strMessage)
{
LogEventViewer(strMessage,EventLogEntryType.Error);
}



} //end class Logging
}
---end of logging.cs--

then, whenver I try to call from ASPX Logging.LogError("an error message"),
I got an error, and when I debug the code, I found that it is failing on the
call to EventLog.SourceExists.
{"Requested registry access is not allowed." }
[System.Security.SecurityException]: {"Requested registry access is not
allowed."}
System.Object: {System.Security.SecurityException}
_className: null
_COMPlusExceptionCode: -532459699
_exceptionMethod: <undefined value>
_exceptionMethodString: null
_helpURL: null
_HResult: -2146233078
_innerException: { }
_message: "Requested registry access is not allowed."
_remoteStackIndex: 0
_remoteStackTraceString: null
_source: null
_stackTrace: {System.Array}
_stackTraceString: null
_xcode: -532459699
_xptrs: 0
HelpLink: null
HResult: -2146233078
InnerException: { }
Message: "Requested registry access is not allowed."
Source: "mscorlib"
StackTrace: " at Microsoft.Win32.RegistryKey.OpenSubKey(String name,
Boolean writable)\r\n at
System.Diagnostics.EventLog.FindSourceRegistration(String source, String
machineName, Boolean readOnly)\r\n at
System.Diagnostics.EventLog.SourceExists(String source, String
machineName)\r\n at System.Diagnostics.EventLog.SourceExists(String
source)\r\n at YJB_Website.classes.Logging.LogEventViewer(String
strMessage, EventLogEntryType objLogEntryType) in
c:\\inetpub\\wwwroot\\yjb_website\\classes\\logging.cs:line 74"
TargetSite: {System.Reflection.RuntimeMethodInfo}


The only way I could get this working is to set <processModel />,
userName="SYSTEM".

But this is not desirable as I don't want to high level of access. and I am
surprised why the code works when run from ASPX but not from a class? Note
also I also have the following settings on machine.config
<identity impersonate="false" userName="Domain\user"
password="password"/>
 
P

Peter O'Reilly

Solution:
- either do not specify an event source and your information will be written
to the application event log*
or
- give the aspnet worker process account administrative rights to the local
machine.


You can read more about it here, in this KB article:
PRB: "Requested Registry Access Is Not Allowed" Error Message When ASP.NET
Application Tries to Write New EventSource in the EventLog
http://support.microsoft.com/default.aspx?scid=kb;en-us;329291&Product=aspnet

In general, http://support.microsoft.com/support is a good place to start
for troubleshooting such matters

*If you already have your custom event source created in the event viewer,
you may be able to write to it w/o admin privileges. IIRC, this may no
longer be the case with .Net v 1.1. a simple test can confirm this.

Hope this helps. Good luck
 
P

Patrick

Does't quite work!

I have done both of what is listed under
http://support.microsoft.com/default.aspx?scid=kb;en-us;329291&Product=aspnet .

Having tried first approach on the Microsoft article, it doesn't work, so I
deleted the Key and tried second approach. Second approach does the same as
first approach, except that that under
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\Te
st, it created a String Key called EventMessageFile, pointing to
C:\WINNT\Microsoft.NET\Framework\v1.1.4322\EventLogMessages.dll (this is on
Win2K SP4)

According to my Trace, the call to .WriteEvent failed with:
System.InvalidOperationException: Cannot open log for source {0}. You may
not have write access. ---> System.ComponentModel.Win32Exception: Access is
denied
--- End of inner exception stack trace ---
at System.Diagnostics.EventLog.OpenForWrite()
at System.Diagnostics.EventLog.WriteEvent(Int32 eventID, Int16 category,
EventLogEntryType type, String[] strings, Byte[] rawData)
at System.Diagnostics.EventLog.WriteEntry(String message,
EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
at System.Diagnostics.EventLog.WriteEntry(String message,
EventLogEntryType type, Int32 eventID, Int16 category)
at System.Diagnostics.EventLog.WriteEntry(String message,
EventLogEntryType type, Int32 eventID)
at System.Diagnostics.EventLog.WriteEntry(String message,
EventLogEntryType type)
at Website.classes.Logging.LogEventViewer(String strMessage,
EventLogEntryType objLogEntryType)System.InvalidOperationException: Cannot
open log for source {0}. You may not have write access. --->
System.ComponentModel.Win32Exception: Access is denied

giving write+modify permission to IWAM_MachineName for
c:\winnt\system32\config\AppEvent.evt does not help solving the problem
either!

The code snipet is as follows:
try
{
EventLog objEventLog;
objEventLog = new EventLog();
objEventLog.Log = "Application";
objEventLog.Source = "TEST";
if ( objEventLog.Log.ToUpper() != "APPLICATION")
{
System.Console.WriteLine("Some other application is
using the source!");
return;
}
objEventLog.WriteEntry(strMessage,objLogEntryType);

}
catch (Exception e)
{
Trace.Write(e);
System.Console.WriteLine(e);
return;
} //end try
 
S

Steven Cheng[MSFT]

Hi Patrick,

I have tested the test.aspx file and the code in Logging.cs. By default
both failed.

Actually, if an web application must create a new event log category, the
application must create a registry key under the HKEY_LOCAL_MACHINE
registry hive, which the ASPNET account cannot do (If we set
username="machine", the ASP.NET web application run with the "ASPNET"
account).

To create the category at run time, you must enable impersonation, and then
you must impersonate an account that has more access rights. Alternatively,
an administrator can create the category, and the application can write to
the category at run time.

I have created one sample for reference. Before creating the new event log
category, I impersonate in the code to the local administrator. After the
new event log category is created, I convert the account to ASPNET again.

The following is the list for the code behind the page:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using System.Security.Principal;
using System.Runtime.InteropServices;


namespace eventtest
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void Button1_Click(object sender, System.EventArgs e)
{
Logging.LogError("an error message");

}
}

public class Logging
{
private const string EVENT_SOURCE = "YJBWEBSITE";
private const string EVENT_LOG = "Applicaiton";



public Logging()
{
//Default constructor
}


public static void LogEventViewer(string
strMessage,EventLogEntryType objLogEntryType)
{
try
{
EventLog objEventLog;

if (!EventLog.SourceExists(EVENT_SOURCE))
{
WindowsImpersonationContext wic = CreateIdentity("administrator",
"machinename", "password").Impersonate();

EventLog.CreateEventSource(EVENT_SOURCE,EVENT_LOG);

wic.Undo();
}

objEventLog = new EventLog();
objEventLog.Source = EVENT_SOURCE;


if ( objEventLog.Log.ToUpper() != EVENT_LOG.ToUpper() )
{
System.Console.WriteLine("Some other application is using the
source!");
return;
}

objEventLog.WriteEntry(strMessage,objLogEntryType);

}
catch (Exception e)
{

System.Console.WriteLine(e);
return;
} //end try

} //end LogEventViewer


public static void LogError(string strMessage)
{
LogEventViewer(strMessage,EventLogEntryType.Error);
}

protected static WindowsIdentity CreateIdentity(string User, string
Domain, string Password)
{
// The Windows NT user token.
IntPtr tokenHandle = new IntPtr(0);

const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_NETWORK = 3;

tokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(User, Domain, Password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);

if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new Exception("LogonUser failed with error code: " + ret);
}

System.Diagnostics.Debug.WriteLine("Created user token: " + tokenHandle);

//The WindowsIdentity class makes a new copy of the token.
//It also handles calling CloseHandle for the copy.
WindowsIdentity id = new WindowsIdentity(tokenHandle);
CloseHandle(tokenHandle);
return id;
}

[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(String lpszUsername, String
lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private extern static bool CloseHandle(IntPtr handle);



} //end class Logging
}

If there is any problem, feel free to let me know.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
P

Patrick

Hi Steven,

thanks for your help, but my points are
1) I have followed the first and second approach stated in
http://support.microsoft.com/default.aspx?scid=kb;en-us;329291&Product=aspnet
to create the event source TEST under the Applicaiton Log. The second
approach, is more advanced in that it create a String Key EventMessageFile
pointing to C:\WINNT\Microsoft.NET\Framework\v1.1.4322\EventLogMessages.dll
(this is on Win2K SP4). Is this not good enough? Is there any reason why
the Event Source has to be created in *run time*?
2) Note, I am no longer calling CreateEventSource anymore, but the call to
WriteEvent is failing as stated in my earlier post.
3) With test.aspx on a Win2K SP4, it works if I set machine.aspx to
impersonate as an account with local administrative rights and does IISRESET
4) With test.aspx on the same Win2K SP4, it stopped working immediately if I
stop using impersonation and IISRESET

Hence, I got a big suspicion that the problem is with access to the Event
Viewer itself!

Note, even if I grante Read, Read+Execute, Write and Modify permissions to
"MyDomain\Authenticated Users" to C:\WINNT\system32\config\AppEvt.cfg,
test.aspx is still failing without impersonation and note- I do *Not* wrong
to run my ASP.NET application as an administrative user!

Steven Cheng said:
Hi Patrick,

I have tested the test.aspx file and the code in Logging.cs. By default
both failed.

Actually, if an web application must create a new event log category, the
application must create a registry key under the HKEY_LOCAL_MACHINE
registry hive, which the ASPNET account cannot do (If we set
username="machine", the ASP.NET web application run with the "ASPNET"
account).

To create the category at run time, you must enable impersonation, and then
you must impersonate an account that has more access rights. Alternatively,
an administrator can create the category, and the application can write to
the category at run time.

I have created one sample for reference. Before creating the new event log
category, I impersonate in the code to the local administrator. After the
new event log category is created, I convert the account to ASPNET again.

The following is the list for the code behind the page:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using System.Security.Principal;
using System.Runtime.InteropServices;


namespace eventtest
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void Button1_Click(object sender, System.EventArgs e)
{
Logging.LogError("an error message");

}
}

public class Logging
{
private const string EVENT_SOURCE = "YJBWEBSITE";
private const string EVENT_LOG = "Applicaiton";



public Logging()
{
//Default constructor
}


public static void LogEventViewer(string
strMessage,EventLogEntryType objLogEntryType)
{
try
{
EventLog objEventLog;

if (!EventLog.SourceExists(EVENT_SOURCE))
{
WindowsImpersonationContext wic = CreateIdentity("administrator",
"machinename", "password").Impersonate();

EventLog.CreateEventSource(EVENT_SOURCE,EVENT_LOG);

wic.Undo();
}

objEventLog = new EventLog();
objEventLog.Source = EVENT_SOURCE;


if ( objEventLog.Log.ToUpper() != EVENT_LOG.ToUpper() )
{
System.Console.WriteLine("Some other application is using the
source!");
return;
}

objEventLog.WriteEntry(strMessage,objLogEntryType);

}
catch (Exception e)
{

System.Console.WriteLine(e);
return;
} //end try

} //end LogEventViewer


public static void LogError(string strMessage)
{
LogEventViewer(strMessage,EventLogEntryType.Error);
}

protected static WindowsIdentity CreateIdentity(string User, string
Domain, string Password)
{
// The Windows NT user token.
IntPtr tokenHandle = new IntPtr(0);

const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_NETWORK = 3;

tokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(User, Domain, Password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);

if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new Exception("LogonUser failed with error code: " + ret);
}

System.Diagnostics.Debug.WriteLine("Created user token: " + tokenHandle);

//The WindowsIdentity class makes a new copy of the token.
//It also handles calling CloseHandle for the copy.
WindowsIdentity id = new WindowsIdentity(tokenHandle);
CloseHandle(tokenHandle);
return id;
}

[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(String lpszUsername, String
lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private extern static bool CloseHandle(IntPtr handle);



} //end class Logging
}

If there is any problem, feel free to let me know.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
P

Patrick

Also, with reference to
http://groups.google.com/groups?hl=...02000&hl=en&lr=&ie=UTF-8&oe=UTF-8&sa=N&tab=wg

how come someone managed to do something very similar to what I am trying to
do, but I can't?!
:'(
Steven Cheng said:
Hi Patrick,

I have tested the test.aspx file and the code in Logging.cs. By default
both failed.

Actually, if an web application must create a new event log category, the
application must create a registry key under the HKEY_LOCAL_MACHINE
registry hive, which the ASPNET account cannot do (If we set
username="machine", the ASP.NET web application run with the "ASPNET"
account).

To create the category at run time, you must enable impersonation, and then
you must impersonate an account that has more access rights. Alternatively,
an administrator can create the category, and the application can write to
the category at run time.

I have created one sample for reference. Before creating the new event log
category, I impersonate in the code to the local administrator. After the
new event log category is created, I convert the account to ASPNET again.

The following is the list for the code behind the page:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using System.Security.Principal;
using System.Runtime.InteropServices;


namespace eventtest
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void Button1_Click(object sender, System.EventArgs e)
{
Logging.LogError("an error message");

}
}

public class Logging
{
private const string EVENT_SOURCE = "YJBWEBSITE";
private const string EVENT_LOG = "Applicaiton";



public Logging()
{
//Default constructor
}


public static void LogEventViewer(string
strMessage,EventLogEntryType objLogEntryType)
{
try
{
EventLog objEventLog;

if (!EventLog.SourceExists(EVENT_SOURCE))
{
WindowsImpersonationContext wic = CreateIdentity("administrator",
"machinename", "password").Impersonate();

EventLog.CreateEventSource(EVENT_SOURCE,EVENT_LOG);

wic.Undo();
}

objEventLog = new EventLog();
objEventLog.Source = EVENT_SOURCE;


if ( objEventLog.Log.ToUpper() != EVENT_LOG.ToUpper() )
{
System.Console.WriteLine("Some other application is using the
source!");
return;
}

objEventLog.WriteEntry(strMessage,objLogEntryType);

}
catch (Exception e)
{

System.Console.WriteLine(e);
return;
} //end try

} //end LogEventViewer


public static void LogError(string strMessage)
{
LogEventViewer(strMessage,EventLogEntryType.Error);
}

protected static WindowsIdentity CreateIdentity(string User, string
Domain, string Password)
{
// The Windows NT user token.
IntPtr tokenHandle = new IntPtr(0);

const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_NETWORK = 3;

tokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(User, Domain, Password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);

if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new Exception("LogonUser failed with error code: " + ret);
}

System.Diagnostics.Debug.WriteLine("Created user token: " + tokenHandle);

//The WindowsIdentity class makes a new copy of the token.
//It also handles calling CloseHandle for the copy.
WindowsIdentity id = new WindowsIdentity(tokenHandle);
CloseHandle(tokenHandle);
return id;
}

[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(String lpszUsername, String
lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private extern static bool CloseHandle(IntPtr handle);



} //end class Logging
}

If there is any problem, feel free to let me know.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
P

Patrick

Note, my test.aspx works on IIS6 on Windows 2003 but not IIS5 on Windows
2000 with SP4, although the Windows 2000 SP4 server is a bit more locked
down. e.g. it has the the High Security Template for Domain Controller
(c:\winnt\security\hisecdc.inf) applied using the Security Configuration &
Analysis snap in. But note that the the ACL has been completely relaxed on
c:\winnt\system32\config\AppEvt.cfg (the file for the Application Event
Log), to give everyone Full control to that file, but still no
joy!.......................

Patrick said:
Also, with reference to
http://groups.google.com/groups?hl=...02000&hl=en&lr=&ie=UTF-8&oe=UTF-8&sa=N&tab=wg

how come someone managed to do something very similar to what I am trying to
do, but I can't?!
:'(
Steven Cheng said:
Hi Patrick,

I have tested the test.aspx file and the code in Logging.cs. By default
both failed.

Actually, if an web application must create a new event log category, the
application must create a registry key under the HKEY_LOCAL_MACHINE
registry hive, which the ASPNET account cannot do (If we set
username="machine", the ASP.NET web application run with the "ASPNET"
account).

To create the category at run time, you must enable impersonation, and then
you must impersonate an account that has more access rights. Alternatively,
an administrator can create the category, and the application can write to
the category at run time.

I have created one sample for reference. Before creating the new event log
category, I impersonate in the code to the local administrator. After the
new event log category is created, I convert the account to ASPNET again.

The following is the list for the code behind the page:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using System.Security.Principal;
using System.Runtime.InteropServices;


namespace eventtest
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void Button1_Click(object sender, System.EventArgs e)
{
Logging.LogError("an error message");

}
}

public class Logging
{
private const string EVENT_SOURCE = "YJBWEBSITE";
private const string EVENT_LOG = "Applicaiton";



public Logging()
{
//Default constructor
}


public static void LogEventViewer(string
strMessage,EventLogEntryType objLogEntryType)
{
try
{
EventLog objEventLog;

if (!EventLog.SourceExists(EVENT_SOURCE))
{
WindowsImpersonationContext wic = CreateIdentity("administrator",
"machinename", "password").Impersonate();

EventLog.CreateEventSource(EVENT_SOURCE,EVENT_LOG);

wic.Undo();
}

objEventLog = new EventLog();
objEventLog.Source = EVENT_SOURCE;


if ( objEventLog.Log.ToUpper() != EVENT_LOG.ToUpper() )
{
System.Console.WriteLine("Some other application is using the
source!");
return;
}

objEventLog.WriteEntry(strMessage,objLogEntryType);

}
catch (Exception e)
{

System.Console.WriteLine(e);
return;
} //end try

} //end LogEventViewer


public static void LogError(string strMessage)
{
LogEventViewer(strMessage,EventLogEntryType.Error);
}

protected static WindowsIdentity CreateIdentity(string User, string
Domain, string Password)
{
// The Windows NT user token.
IntPtr tokenHandle = new IntPtr(0);

const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_NETWORK = 3;

tokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(User, Domain, Password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);

if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new Exception("LogonUser failed with error code: " + ret);
}

System.Diagnostics.Debug.WriteLine("Created user token: " + tokenHandle);

//The WindowsIdentity class makes a new copy of the token.
//It also handles calling CloseHandle for the copy.
WindowsIdentity id = new WindowsIdentity(tokenHandle);
CloseHandle(tokenHandle);
return id;
}

[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(String lpszUsername, String
lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private extern static bool CloseHandle(IntPtr handle);



} //end class Logging
}

If there is any problem, feel free to let me know.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
S

Steven Cheng[MSFT]

Hi Patrick,

Thanks for your effort and time!

I would like to restate the current status as following. Please check if I
understood the problem correctly.

1. Now you are directly calling "WriteEntry" to add the event to the Event
Log. However, the error message still appear.

2. When you use impersonation on the Windows 2000 SP4 machine, the
test.aspx page works fine. However, without impersonation, it will fail.

If I have misunderstood, please don't hesitate to let me know.

Patrick, as we have discussed, if we do not enable impersonation, the
default account (ASPNET on Windows 2000) for ASP.NET work process do not
have permission to create the new event log category. This is the cause for
the error message.

However, by default the account "ASPNET" has permission to add one event
item with "WriteEntry". The following code also works fine on my side. Can
you help to double confirm with the following code on your side again?
Thanks for your help!

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;


namespace eventtest
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void Button1_Click(object sender, System.EventArgs e)
{
Logging.LogError("an error message");

}
}

public class Logging
{
private const string EVENT_SOURCE = "YJBWEBSITE";
private const string EVENT_LOG = "Applicaiton";



public Logging()
{
//Default constructor
}


public static void LogEventViewer(string
strMessage,EventLogEntryType objLogEntryType)
{
try
{
EventLog objEventLog;

objEventLog = new EventLog();
objEventLog.Source = "application";

objEventLog.WriteEntry(strMessage,objLogEntryType);

}
catch (Exception e)
{

System.Console.WriteLine(e);
return;
} //end try

} //end LogEventViewer


public static void LogError(string strMessage)
{
LogEventViewer(strMessage,EventLogEntryType.Error);
}

} //end class Logging
}

If there are any new findings, please feel free to let me know. Thanks!

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
P

Patrick

I have added in some Trace code and changed the code to do the logging on
Page_Load and tested(code appended below).

Note, it works on a (not very locked down) Windows XP Professional SP2
running IIS5.1, but not on a fairly locked down Windows 2000 SP4 running
IIS5.0. The exceptions from trace is:
before writeSystem.InvalidOperationException: Cannot open log for source
{0}. You may not have write access. --->
System.ComponentModel.Win32Exception: Access is denied
--- End of inner exception stack trace ---
at System.Diagnostics.EventLog.OpenForWrite()
at System.Diagnostics.EventLog.WriteEvent(Int32 eventID, Int16 category,
EventLogEntryType type, String[] strings, Byte[] rawData)
at System.Diagnostics.EventLog.WriteEntry(String message,
EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
at System.Diagnostics.EventLog.WriteEntry(String message,
EventLogEntryType type, Int32 eventID, Int16 category)
at System.Diagnostics.EventLog.WriteEntry(String message,
EventLogEntryType type, Int32 eventID)
at System.Diagnostics.EventLog.WriteEntry(String message,
EventLogEntryType type)
at eventtest.Logging.LogEventViewer(String strMessage, EventLogEntryType
objLogEntryType)

What other security permissions are required just to write to the event
viewer?

As discussed, previously, on the win2K SP4 box
1) ACL has been completely relaxed on c:\winnt\system32\config\AppEvt.cfg
(the file for the Application Event
Log), to give everyone Full control to that file
2) The Event Source was entered as a Key under
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\
3) it has the the High Security Template for Domain Controller
(c:\winnt\security\hisecdc.inf) applied using the Security Configuration &
Analysis MMC snap in.

What other security permissions are required just to write to the event
viewer? As you have suggested and as stated in
http://groups.google.com/groups?hl=...x.gbl&rnum=1&prev=/groups?q=Security%20Permis
sion%2520Event%2520Viewer%2520write%2520windows%25202000%26hl%3Den%26lr%3D%2
6ie%3DUTF-8%26oe%3DUTF-8%26sa%3DN%26tab%3Dwg, the standard ASP.NET worker
process should have permission to write to the Event Viewer using an
existing event source!

-Standard Assembly.Info and Global.asax file with a ASP.NET C# Project in
Visual Studio 2003 Enterprise Architect version.
---start of webform1.aspx----
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="eventtest.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:Button id="Button1" style="Z-INDEX: 101; LEFT: 168px;
POSITION: absolute; TOP: 112px" runat="server"
Text="test" Width="96px" Height="24px"></asp:Button>
</form>
</body>
</HTML>
---end of webform1.aspx----


---start of webform1.aspx.cs----
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;

namespace eventtest
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{

protected System.Web.UI.WebControls.Button Button1;

private void Page_Load(object sender, System.EventArgs e)
{
Logging.LogError("an error message");
// Put user code to initialize the page here
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form
Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion


}

public class Logging
{
private const string EVENT_SOURCE = "TEST";
private const string EVENT_LOG = "Application";



public Logging()
{
//Default constructor
}


public static void LogEventViewer(string
strMessage,EventLogEntryType objLogEntryType)
{
try
{
EventLog objEventLog;

objEventLog = new EventLog();
objEventLog.Source = EVENT_SOURCE;
objEventLog.Log = EVENT_LOG;
Trace.Write("before write");

objEventLog.WriteEntry(strMessage,objLogEntryType);

Trace.Write("after write");

}
catch (Exception e)
{
Trace.Write(e);
System.Console.WriteLine(e);
return;
} //end try
finally
{
Trace.Flush();
}

} //end LogEventViewer


public static void LogError(string strMessage)
{
LogEventViewer(strMessage,EventLogEntryType.Error);
}

} //end class Logging
}
---end of webform1.aspx.cs----

---Start of Web.config---
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<trace autoflush="true" indentsize="3">
<listeners>

<add name="myListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="c:\\temp\\CMSTraceFile.txt" />
<remove type="System.Diagnostics.DefaultTraceListener"/>
</listeners>

</trace>
</system.diagnostics>
<system.web>

<!-- DYNAMIC DEBUG COMPILATION
Set compilation debug="true" to enable ASPX debugging. Otherwise,
setting this value to
false will improve runtime performance of this application.
Set compilation debug="true" to insert debugging symbols (.pdb
information)
into the compiled page. Because this creates a larger file that
executes
more slowly, you should set this value to true only when debugging
and to
false at all other times. For more information, refer to the
documentation about
debugging ASP.NET files.
-->
<compilation
defaultLanguage="c#"
debug="true"
/>

<!-- CUSTOM ERROR MESSAGES
Set customErrors mode="On" or "RemoteOnly" to enable custom error
messages, "Off" to disable.
Add <error> tags for each of the errors you want to handle.

"On" Always display custom (friendly) messages.
"Off" Always display detailed ASP.NET error information.
"RemoteOnly" Display custom (friendly) messages only to users not
running
on the local Web server. This setting is recommended for security
purposes, so
that you do not display application detail information to remote
clients.
-->
<customErrors
mode="RemoteOnly"
/>

<!-- AUTHENTICATION
This section sets the authentication policies of the application.
Possible modes are "Windows",
"Forms", "Passport" and "None"

"None" No authentication is performed.
"Windows" IIS performs authentication (Basic, Digest, or
Integrated Windows) according to
its settings for the application. Anonymous access must be
disabled in IIS.
"Forms" You provide a custom form (Web page) for users to enter
their credentials, and then
you authenticate them in your application. A user credential
token is stored in a cookie.
"Passport" Authentication is performed via a centralized
authentication service provided
by Microsoft that offers a single logon and core profile services
for member sites.
-->
<authentication mode="Windows" />

<!-- AUTHORIZATION
This section sets the authorization policies of the application.
You can allow or deny access
to application resources by user or role. Wildcards: "*" mean
everyone, "?" means anonymous
(unauthenticated) users.
-->

<authorization>
<allow users="*" /> <!-- Allow all users -->
<!-- <allow users="[comma separated list of users]"
roles="[comma separated list of roles]"/>
<deny users="[comma separated list of users]"
roles="[comma separated list of roles]"/>
-->
</authorization>

<!-- APPLICATION-LEVEL TRACE LOGGING
Application-level tracing enables trace log output for every page
within an application.
Set trace enabled="true" to enable application trace logging. If
pageOutput="true", the
trace information will be displayed at the bottom of each page.
Otherwise, you can view the
application trace log by browsing the "trace.axd" page from your
web application
root.
-->
<trace
enabled="true"
requestLimit="10"
pageOutput="false"
traceMode="SortByTime"
localOnly="false"
/>

<!-- SESSION STATE SETTINGS
By default ASP.NET uses cookies to identify which requests belong
to a particular session.
If cookies are not available, a session can be tracked by adding a
session identifier to the URL.
To disable cookies, set sessionState cookieless="true".
-->
<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data
source=127.0.0.1;Trusted_Connection=yes"
cookieless="false"
timeout="20"
/>

<!-- GLOBALIZATION
This section sets the globalization settings of the application.
-->
<globalization
requestEncoding="utf-8"
responseEncoding="utf-8"
/>

</system.web>

</configuration>
---End of web.config----
 
P

Patrick

Environment- Windows 2000 SP4, IIS5.0, domain controller, .NET Framework
1.1, High Security Template for Domain Controller applied

Running- Microsoft Content Management Server 2002 SP1A (ASP.NET
application), ASP Application, SQL Server

What I have been doing
1) Testing with ASP.NET process Model, etc. to get ASP.NET to write to the
Event Viewer
2) Deploying a new COM+ which is used by a seperate ASP application (it
involves
2.1) removing serveral classes from COM+, restarting server, deleting old
DLL, copying over new DLL, installing new DLL
2.2) Changing Domain Security Policy to lock out accounts after 4 invalid
logons, secedit /refreshpolicy machine_policy

Now, everything have stopped working!
In System Log:
Event Type: Error
Event Source: DCOM
Event Category: None
User: N/A
Description:
DCOM got error "Overlapped I/O operation is in progress. " and was unable to
logon .\IWAM_YJBWEBLIVE in order to run the server:
{3D14228D-FBE1-11D0-995D-00C04FD919C1}

In Application Log:
Event Type: Error
Event Source: ASP.NET 1.1.4322.0
Event Category: None
Event ID: 1007
User: N/A
Description:
aspnet_wp.exe could not be launched because the username and/or password
supplied in the processModel section of the config file are invalid.

Event Type: Error
Event Source: ASP.NET 1.1.4322.0
Event Category: None
Event ID: 1084
User: N/A
Description:
aspnet_wp.exe could not be started. The error code for the failure is
80004005. This error can be caused when the worker process account has
insufficient rights to read the .NET Framework files. Please ensure that the
..NET Framework is correctly installed and that the ACLs on the installation
directory allow access to the configured account.

Research revealed that this could be caused by IWAM_machinename passwords
getting out of sync, I have reviewed:
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q296851
http://support.microsoft.com/?kbid=297989

I have reset password in AD for IWAM_MachineName, used adsutil.vbs to set
password of IWAM_MachineName to the password I set manually in AD

I tried to run cscript synciwam.vbs -v, but I get
Updating Applications:
Name: IIS-{www.youth-justice-board.gov.uk//ROOT/cgi-bin} Key:
{CB75A528-444A-484
A-83AF-4DA3849146A8}
Name: IIS-{Administration Web Site//ROOT/cgi-bin} Key:
{F7FF5789-0853-4BC8-BE09-
8057B84C15A3}
Name: IIS Out-Of-Process Pooled Applications Key:
{3D14228D-FBE1-11D0-995D-00C04
FD919C1}
Error: 80110414:

Also tried making IUSR_MachineName and IWAM_MachineName temporarily member
of Administrators group first, but still that does not allow the script to
run without error!

Now, I can't even run a simple test.asp or test.aspx with no code in it!
when I try to load test.asp, I get the DCOM error in system log. when I try
to load the test.aspx, I get the 2 asp.net error in the Applicaiton log

At present, machine.config is set to
1) no impersonation settings
2) processModel set to run as "machine" user

I could get ASP.NET pages running if I change processModel to run as
"SYSTEM" user, but this is not the settings I have on the live system.
Also, IWAM_MachineUser does have full control to the "Temporary ASP.NET
Files" folder!

SOS !
 
P

Patrick

It has always work with IIS5.0 which is the version with Windows 2000
server.

IIS5.1 if I remember rightly is for Windows XP only.
 
P

Patrick

IIS problem resolved, IWAM_MachineName account was locked out.

However, ASP.NET still can't write to EventViewer!!
 
A

Aaron Bertrand - MVP

by what I know, you need IIS 5.1 or version above to run .net
applications.

No, this is not true! Where do people get this "advice"?
 
A

Aaron Bertrand - MVP

However, ASP.NET still can't write to EventViewer!!

What does "can't write" mean? Do you get an error message? If so, what is
it? Have you fixed the permissions for the IWAM and IUSR accounts? Have
you considered using Windows authentication (it's odd you would want
anonymous users to be able to write to the event log).
 
S

Steven Cheng[MSFT]

Hi Patrick,

From the error message "aspnet_wp.exe could not be launched because the
username and/or password supplied in the processModel section of the config
file are invalid.", I believe this error is related with the account
settings.

Actually, when we set "machine" as the user in processModel, ASP.NET work
process is running with the account "ASPNET". Please perform the following
steps to make the asp.net web application works:

1. I would like to double confirm the settings in machine.config. Please
make sure the user name and password is:

userName="machine" password="AutoGenerate"

Note: Please do not overwrite "AutoGenerate" with another password.

2. Delete the "ASPNET" account.

This is a local account, not a domain account.

3. In the command window, locate the following directory:

C:\<Windows Directory>\Microsoft.Net\Framework\VersionNote:

You must replace <Windows Directory> in this path with the correct
directory for your system and replace <Version> with the version of the
.NET Frame work installed on your system.

4. Type "aspnet_regiis -i" (without the quotation marks) to configure the
required application mappings correctly.

This will reinstall ASP.NET on the machine.

Now, please try to run the ASP.NET web application again. If there are any
new findings, please don't hesitate to let me know.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
P

Patrick

Actually, the "aspnet_wp.exe could not be launched because the username
and/or password supplied in the processModel section of the config file are
invalid." error was caused by the the IWAM_MachineName user account being
locked out. The problem was resolved by unlocking the user.

anyway, I am still getting the error with the call to WriteEvent:
System.InvalidOperationException: Cannot open log for source {0}. You may
not have write access. ---> System.ComponentModel.Win32Exception: Access is
denied --- End of inner exception stack trace --- at
System.Diagnostics.EventLog.OpenForWrite() at
System.Diagnostics.EventLog.WriteEvent(Int32 eventID, Int16 category,
EventLogEntryType type, String[] strings, Byte[] rawData) at
System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType
type, Int32 eventID, Int16 category, Byte[] rawData) at
System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType
type, Int32 eventID, Int16 category) at
System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType
type, Int32 eventID) at System.Diagnostics.EventLog.WriteEntry(String
message, EventLogEntryType type) at
_ASP.eventLog_aspx.__Render__control1(HtmlTextWriter __output, Control
parameterContainer)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top