Writing log to Windows Event Viewer - c#

Is it possible for a windows service/web application (c#) to write log entries where its running under a windows domain account that is NOT a local admin?
I have tried both of the following for a NON admin windows domain account:
Writing to the Application log (with a 'Test' source). but this gave me 'Access Denied' error.
Initially setup a new custom log called 'Test' that would have appeared under 'Applications and Service Logs' using a local admin windows user account.
I then tried to write logs to this using a non admin windows user account but still ended up getting 'Access denied' error.
I have seen suggestions where the registry needs to be modified but i really don't want to go down that route as it feels hacky and..well..just not right!
I can get both options above to work when i switch the windows user to a local admin, but i don't want this.
Any suggestions greatly appreciated..
(Apologies in advance if this is duplicate POST)

You need to grant access to the log. See Delegating access to the event logs
Open Registry Editor.
Navigate to the following registry path:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog
You will see that there are keys available for each event log. Select the event log for which you want to delegate access.
Add a new key with the name CustomSD to the event log you selected.
Add a new String value to the CustomSD key. The name of this string is not required, but it represents the access control list for the event log in the Security Descriptor Definition Language (SDDL) syntax. In this procedure this value will be referred to as SDDLACL.
As for the SDDL, see Security Descriptor String Format

Related

Cannot write to the Event log

edI have C# ASP.NET 4.5 Webform application and use the following code:
if (!EventLog.SourceExists(sSource)) EventLog.CreateEventSource(sSource, sLog);
EventLog.WriteEntry(sSource, message, level);
Since the first line was failing I created
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application\IDDISLOG in registry
I get the following exception on WriteEntry Method:
Cannot open log for source 'IDDISLOG'. You may not have write access.
Searched other similar questions but none worked for me.
Here is what I have done so far:
Added "Network service" to the project file folder
Added Network service to and gave it full access.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog
Added Nertwork service to and gave it full access.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Security
Checked and saw w3wp.exe *32 process runs with User Name ASP.Net v4.0.
So added ASP.Net v4.0 to
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog
Still, error remains
Your user account may not have sufficient privileges to create an event source, which only administrator accounts can do. If you can log in as an administrator, either run your code again or add a folder here: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application\IDDISLOG
That should allow your application to write to the event log with that source. You may need to configure the actual registry entry further to suit your needs.
In IIS (Windows server), you should change de identity used by de app pool, so the new identity has permission to write to the event log.
Select the app pool and advanced settings. then edit and insert a custom account, althoug local system will suffice. If you use a custom account be sure not to use a user whose password is going to expire, because when it happens logging to event log will fail.

C# EventLog.Delete Access Denied

I have read other questions on SO in regards to security and registry keys, nothing has helped me solve my particular use case scenario.
Here's my scenario:
What I'm Trying To Do
I want to, in code, delete a windows event log.
The Problem
When executing the function, I receive a System.ComponentModel.Win32Exception. The exception message is "Access is denied".
How I Am Doing It Currently
I am using an impersonator function that I wrote which wraps around the EventLog.Delete function, it drops me into a user context that has full access to the EventLog Registry Hive. Subsequently the logs I am interested in also have full access for this particular user.
My Question
Why do I receive a "Access Is Denied" if the user I am running under (through impersonation) has full access to the log in question? I've tested my Impersonation function and it works as expected for other code I've written. I don't get why I would get access denied for this.
In another scenario with my impersonation function it works just fine, for example if I tried to write to a file that the user context that is running the program does not have write access to, then I would not be able to write to the text file, however if I use my impersonation to drop into a user context that does have write access then it works just fine (I can write to the file). So I just don't understand why the same concept can't be applied to registry keys.
What am I missing here?
The Code
Exception Message
My Test
Where sw-test is a user I created for testing purposes, it has full access permissions to the registry we are trying to delete.
[TestMethod]
public void DeleteEventLog_ValidatedUser_DeleteLog()
{
using (new Impersonator(Environment.UserDomainName, "sw-test", "pswd"))
{
Logging logging = new Logging();
logging.DeleteEventLog("testLog");
}
}
Okay I eventually got around to figuring this out, there were two issues at play here that were causing the mentioned exception being thrown, they are as follows:
1. Visual Studio was NOT running in administrator mode.
Not running visual studio in administrator mode was one part of the problem, this seems to be associated with access tokens in the windows OS. According to a source I read, if I run a program without UAC on (which is my scenario, I have it off), then the program being run gets a copy of my access token. However if I have UAC enabled, the program gets a copy of my access token but it is a restricted access token. (see: What precisely does 'Run as administrator' do?) - To be honest this doesn't really make sense in my case, why do I have to run as admin if I have UAC off? Shouldn't visual studio have an unrestricted copy of my access token? I am in the administrator group with UAC off...
2. Not Specifying NewCredentials As a Logon32Type In Impersonation
I don't really understand it but as soon as I specified this for my impersonation everything started working perfectly, I read a blog about it, it talks about how it was introduced in the VISTA days and how it was mainly used to specify credentials to outbound network connections to servers, and was mainly used to remedy security-related issues server-side. Don't see how it correlates to interfacing with local event logs though. (see: https://blogs.msdn.microsoft.com/winsdk/2015/08/25/logonuser-logon32_logon_new_credentials-what-is-this-flag-used-for/)
Code
using (new Impersonator(Environment.UserDomainName, "sw-test", "pswd", Advapi32.Logon32Type.NewCredentials))
{
EventLog.CreateEventSource("testSource", "testLog");
EventLog.Delete("testLog");
}
Where the NewCredentials is an int 9

"The handle is invalid" error when writing to eventlog using ASP.NET

I am working with an ASP.NET 2.0 application (created by my predecessor). Users log into it with AD credentials, and everything done within the app uses those credentials. I modified a page in the application that has nothing to do with event logging, and now my users get this error:
Here is the relevant code from the global.asax file:
public void LogException(Exception e)
{
string exceptionXml = RenderException(e, true);
_EventLog.WriteEntry("Exception of type " + e.GetType().FullName + " occurred.\n\n" + exceptionXml, EventLogEntryType.Error);
}
RenderException() just puts the exception XML into a flat string, removing white spaces.
I am at a loss on how to get rid of this error. I have tried re-publishing the website with an iisreset. I have tried restarting the web server (2k3 w/ iis 6.0), flushing the app pool. I have also tried modifying the permissions in the registry for the top-level event log key. Can anyone tell me how to get rid of this error? It does not happen on my computer, so it is very hard to replicate. Also, the browser used does not seem to matter. The previous version will work for the same persons getting this error.
By default the ASPNET user cannot access the existing event logs categories.
If you do want to write messages to the event log you must create your own category
Launch RegEdit
Navigate to HKEY_LOCAL_MACHINE\SYSTEM\
CurrentControlSet\Services\EventLog\
From the menu, select Edit->Permissions
Click the Add button and write ASPNET. (if ASP.NET is running under a different user id, use that id instead)
Click OK.
Select the newly added user from the list (ASP.NET Machine User by default).
Click on Full Control in the Allow column.
Click OK.
You can also check that the user, under which the applications is running, belongs to the correct group, for example IIS_WPG
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/3648346f-e4f5-474b-86c7-5a86e85fa1ff.mspx?mfr=true
You appear to be calling an instance method of the EventLog class on the _EventLog instance:
_EvengLog.WriteEvent(message, ...);
But according to MSDN documentation for the EventLog class:
Any instance members are not guaranteed to be thread safe.
I suspect this is a likely source of your problem, and would recommend you use one of the static methods (which are guaranteed to be thread safe):
System.Diagnostics.EventLog.WriteEvent(source, message, ...);
Alternatively you could implement your own synchronization, but I wouldn't recommend this.

Why does my Event Log source keep getting put under "Application" in the registry instead of <log>?

I'm trying to create a windows service and I need it to be able to write to the event logs. I've added an EventLog component to my Service project, and set the Log property to be ccs_wscln_log and the Source property to be ccs_wscln (same name as the service).
I have also created and installer for this project. My problem is that whenever I install the service, it creates the ccs_wscln registry key under
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application
when it SHOULD be
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\ccs_wscln_log.
The problem with this is that when I try to launch the service, I get an error that says
"The source 'ccs_wscln' is not registered in log 'ccs_wscln_log'. (It is registered in log 'Application'). The source and Log properties must be matched, or you may set Log to the empty string, and it will automatically be matched to the source property'.
I've found that if I delete the ccs_wscln registry key under the Application folder, when I start the service it will run and generate the ccs_wscln_log entry under EventLog. So my question is, when I install the application, why is it creating an entry for me automatically under Application, and how do I prevent it from doing this?
I found another post on SO that said I need to restart my computer if I had installed it before under Application, so I tried that but when I reloaded the solution, I couldn't even bring up the designer because it was complaining that the registry entry was missing and it would still install under Application anyways.
I created a tutorial for creating a Windows service from scratch using C#. I address the issue of writing to an application-specific log. See Step 9 here for details.
I think, you would need following in your ServiceInstaller class.
this.Installers.Clear();
Above code needs to be just before you are adding a range of installers.
That is because, EventLogInstaller is added by default. Calling clear will remove it.
Alternatively, you can loop through the installers collection, select the specific type (EventLogInstaller) and assign it required LogName and EventSource name.

Problem when trying to use EventLog.SourceExists method in .NET

I am trying to use eventlogs in my application using C#, so I added the following code
if (!EventLog.SourceExists("SomeName"))
EventLog.CreateEventSource("SomeName", "Application");
The EventLog.SourceExists causes SecurityException that says
"The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security."
I am running as administrator in Windows 7.
Any help would be appriciated.
This is a permissions problem - you should give the running user permission to read the following registry key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog
Alternaitvely you can bypas the CreateEventSource removing the need to access this registry key.
Both solutions are explained in more detail in the following thread - How do I create an Event Log source under Vista?.
Yes, it's a permissions issue, but it's actually worse than indicated by the currently accepted answer. There are actually 2 parts.
Part 1
In order to use SourceExists(), the account that your code is running under must have "Read" permission for the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog key and it must also have "Read" permissions on each of the descendant-keys. The problem is that some of the children of that key don't inherit permissions, and only allow a subset of accounts to read them. E.g. some that I know about:
Security
State
Virtual Server
So you have to also manually change those when they exist.
FYI, for those keys (e.g. "State") where even the Administrator account doesn't have "Full Access" permission, you'll have to use PsExec/PsExec64 to "fix" things. As indicated in this StackOverflow answer, download PsTools. Run this from an elevated command prompt: PsExec64 -i -s regedit.exe and you'll them be able to add the permissions you need to that key.
Part 2
In order to successfully use CreateEventSource(), the account that your code is running under must have "Full Control" permissions on HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog as well as have "Full Control" permissions on the log you're adding the new source to.
But wait, there's more...
It is also important to know that both CreateEventSource() and WriteEntry() call SourceExists() "under the hood". So ultimately, if you want to use the EventLog class in .Net, you have to change permissions in the registry. The account needs "Full Control" on the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog key and "Read" for all children.
Commentary: And I believe all of this mess is because when Microsoft originally designed the EventLog, they decided it was critical that people would be able to log something by "Source" without needing to know what log that "Source" went with.
Short tip:
One event source is registered during Service instalation (if application is Windows Service), and can be used without Security Exception with low-profile process owner (not Administrator)
I perform service installation / run with C# code in typical way from SO/ MSDN
Important is property ServiceName in class System.ServiceProcess.ServiceBase .
Good afternoon,
The simplest is that you run vs2019 as an administrator, so when debugging or excute the service, it will run correctly without generating the exception.

Categories