C# EventLog.Delete Access Denied - c#

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

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.

UnauthorizedAccessException while accessing Microsoft.Web.Administration.ServerManager.Site on Windows 8.1

Does someone get any hint for accessing Microsoft.Web.Administration.ServerManager.Sites collection on Win8.1 (and Win8) if the user got no right on file "%SystemRoot%\System32\inetsrv\config\redirection.config" ?
Because the user will get UnauthorizedAccessException in this case...
More largely, on Win8 you can get into trouble on any Microsoft.Web.Administration.ServerManager property if your user has no right on "%SystemRoot%\System32\inetsrv\config".
This works perfectly on Win7, W2008 and W2012..
HowTo: http://www.iis.net/learn/manage/scripting/how-to-use-microsoftwebadministration
I need this in a WiX c# Custom Action launched in 'client' step (while in UI) to browse installed Web sites and applications on them for unicity check on new WebApplication name.
Of course, I cant find any relevant answer for this while googling. There are only a few answers out and they hint to launch with elevated privilege or change the rights on the folder, witch of course is not feasible in a regular user setup UI process.
Ex: http://sharepointyankee.com/2011/03/30/system-unauthorizedaccessexception-filename-redirection-config/
Just for information, it seems to be no way to get rid of this...
So I choose to modify my Custom Action to ignore this case by catching UnauthorizedAccessException and still set success for unicity check and return a success for the CA call.
In this case in client step I won't get a failure, with counterpart that I can't get the real result of the unicity check. But I get the result if it wont fail with UnauthorizedAccessException and I can spawn a dialog to the user inviting him to change the site name.
Then in server step where by the way this check ever works I do the same test to be able to fail the setup with a clear message if the website is not unique.
This is not the best for the user who must then restart the setup to change the site name but it works and avoid strange failures by trying to create two websites with the same 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.

Determining Write Permissions to the Application Folder

I have a C# application, and I need to dump some output to a log file during operation. I am wanting to give the user the option of where to locate the log file, but by the client request it needs to default to the current application location, which is normally /Program Files/.
When I deploy my application on a Win7/Vista machine, though, the application does not write the log file unless I run the program as an Administrator. At the same time, it seems to be silently handling the case where it cannot write the file, as I am currently handling all exceptions being thrown during the file creation and writing process.
I am currently trying to detect lack of write permission by both:
A) Creating a DirectorySecurity object by calling "Directory.GetAccessControl()" and
B) Checking security priviledges with the "SecurityManager.IsGranted(permissions)" method,
but A does not throw an exception when I expect it to, and B returns true every time.
I have seen numerous posts related to this topic, but they all give the solution of just writing to Application.UserAppDataFolder or some variation of it. My client has specifically asked to default to the current Application path, so I need to at least find a way to gracefully warn them when writing the log file is going to silently fail.
Note: My current code works find on Windows XP (since there are no UAC, I assume). Basically all I need to know is why all my calls are telling me that writing the file is going fine, when the file is never created at all unless I am running as Admin.
Thanks!
Windows Vista and 7 will write files to the Program Files directory just fine.
Well, not really, but the program thinks it's just fine. In reality, the file is written to the current user's VirtualStore directory; that is, in %userprofile%\AppData\Local\VirtualStore\Program Files
You can include a manifest file to disable this behavior for your application to get the results you expect.
You can force the os to run your app as Admin.
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
There are three ways your app can run - elevated, deliberately not elevated (manifest saying asInvoker), or accidentally not elevated (no manifest). Elevated apps will be able to write to Program Files. Deliberately not elevated apps will get access denied. Accidentally not elevated apps will succeed but the file will be written elsewhere. This last case is what's happening to you. It didn't silently fail. You just don't know where the files are. See http://www.gregcons.com/KateBlog/FindingFilesYoureSureYouWrote.aspx for screenshots.
Therefore if the users insist on the current directory, you should add a manifest requesting asInvoker. You will then get AccessDenied and they will see the error message. I think they are odd for wanting this. Ask them if they are ok with one extra click to find them: if so, keep your app using virtualization (I really disapprove) by having no manifest and then train them to click the Compatibility Files button.
My preference: write elsewhere and manifest to asInvoker. My second choice: stick with current directory, no manifest, train them to find virtualized files. My third choice: stick with current directory, manifest to asInvoker, users see error messages when log files are not written, but logs are lost.
I am experiencing the same problem. I have an xml file that i am writing to...When I install the app(C sharp) and try to run the application am getting an exception due to write permission. When I change the file permission (give read permission to users) it is working ok..
The ultimate test for whether you have the rights to write a file is to open it for writing.
I.e.
try
{
File.Open(path, FileMode.OpenOrCreate);
...
}
catch(SecurityException)
{
... it failed for security reasons
}
catch(Exception)
{
... it failed for other reasons
}
Besides Stefan P.'s suggestion to elevate the app to run as admin, you could also modify the installation folder permission on install to to add the Users group to have write access. Then the application would work as well.
Moving the log file location would be the best option though.

security exception accessing registry when the program runs as scheduled task

the following small line throws a System.Security.SecurityException: Requested registry access is not allowed:
RegistryKey _key = HKLM.OpenSubKey("path\\to\\my settings", false);
Now.. what's the point some would ask? The point is that this runs ONLY when I am logged on. The exception is thrown if the program runs as scheduled task and nobody is logged on.
the user who runs that task is local administrator
the program does not run from a network share, it is located on the local disk
I even tried setting Code Access Security
the user has the rights to log on as a batch job
I have XP SP3 with all patches applied. The program is written in C# .Net 2.0 (tested 3.5 too)
Does anyone know whats the point here?
Torsten
EDIT: see http://gist.github.com/638576
Mhhhh...it seems related to Authorization problem too. Have you tried to use the API: OpenSubKey(...., RegistryKeyPermissionCheck) to see if something change? I guess it could be related to parent key and its authorization.
Try to see: http://msdn.microsoft.com/it-it/library/microsoft.win32.registrykeypermissioncheck.aspx (in your language). I hope it could help you...
Can you adapt this
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
string isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator) ? "Yes" : "No";
to check that the process really is successfully impersonating when there's no current user?
It seems that this is a problem of this specific computer. I tested it on another workstation and it works even without administrator privileges.
I assumed this - the program did run for years without any problems... Anyway, thanks to all!

Categories