Cant Access Registry even with Elevated Permission - c#

I am making a Service Program where it will change the start up type of certain service.
My Current code does not even let me open the registry for writing, even when I "Run As Admin".
Code:
ServiceKey = Registry.LocalMachine;
ServiceKey = ServiceKey.OpenSubKey(#"SYSTEM\CurrentControlSet\services\" + ServiceName, true);
ServiceKey.SetValue("Start", 2, RegistryValueKind.DWord);
However, I get this error: Requested Registry Access is not allowed.
Anyone know a solution ?
(PS. I know there are other way's I could be doing this, but it's bother me how It's not letting me Access the registry.) My program is also running as Any CPU.

The way to change a service's configuration is not to whack the registry. You use the service control manager. MSDN even has a sample program that changes a service's start type. I found this page by going to About Services, then clicking Service Configuration Programs, then Service Configuration.

Found the problem, on some registry, if you check the "Permission", you will notice that not even an admin has the permission to change the registry. You can change the permission your self but on my case, I will find a different approach to editing the service start up.

Related

How to keep "Allow Service to interact with desktop" checked by default at the time of windows service installation

I have created a windows service which should open and run a ABC.exe application. I know it is a bad practice to do this dont downvote for this reason coz i dont have any other option at the moment. i have done research about this a lot and found out a work around as making it interactive.i used this link: https://code.msdn.microsoft.com/windowsapps/CSCreateProcessAsUserFromSe-b682134e
but the problem i am facing right now is user have to manually set Local System Account and check the "Allow Service to interact with Desktop" box. all i want to do right now is set it checked by default at the time of installation. so when user installs the service it should be already checked and the service should be in the running state(dont have to manually start the service-i am done with this part). i have seen some similar post here but they all show way to start the service from external app like creating another console app and using system.management.managementobject. i want to know if there is any way to add some code in the service itself and where to add it?
ps.: i am creating this service for windows vista+ systems.
please help as i am stuck on this problem for quite a while. Thanks in advance.
What i suggest you do is modify the value directly in registry
In the installer class, override the OnCommitted(System.Collections.IDictionary savedState) method.
In that method, modify the registry key that ensures this setting, like so:
protected override void OnCommitted(System.Collections.IDictionary savedState)
{
base.OnCommitted(savedState);
string regKey = "SYSTEM\\CurrentControlSet\\Services\\MyServiceName";
var key = Registry.LocalMachine.OpenSubKey(regKey, RegistryKeyPermissionCheck.ReadWriteSubTree)
?? Registry.LocalMachine.CreateSubKey(regKey, RegistryKeyPermissionCheck.ReadWriteSubTree);
// might need to check the result, should be hex 110 or Decimal 272
key.SetValue("Type", 272, RegistryValueKind.DWord);
}

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.

What is permission required to use OpenRemoteBaseKey?

I had asked about this in some other thread and got the link to access remote registry. But the problem I am now facing is I am not able to add any values in to registry. I was trying to add some values to an existing entry in a registry by using following code but not doing anything in remote registry:
RegistryKey rk;
rk = RegistryKey.OpenRemoteBaseKey(
RegistryHive.CurrentUser, ReadServerName());
regkey = rk.OpenSubKey(LeafRegistry.LeafRoot + "\\sim\\NewView\\");
regkey.SetValue("runsystem", SIMserver);
UPDATE
RegistryHive.LocalMachine will work here, I can open and do all operation, but then why for RegistryHive.CurrentUser ? What I am saying is in the above code I will get value for 'rk' but I cannot get value for regkey which will become null, I think for CurrentUser OpenSubKey is not working.
UPDATE
When I analyzed in depth, I saw for except this particular key, all other keys are accessible. I am wondering what is going on for this specific key, I checked permission also after right clicking, but couldn't see it?
You will almost certainly require permissions in most cases when you are attempting to change registry values on remote machines across a network. Also, in a lot of cases, even where you can amend the registry values they can be refreshed via Group Policies and reverted back.
It could be that there are certain parts of the registry that you are restricted from editing,
If you don't have administrator privelages then I think you will come unstuck.
This is not going to work. Suppose the user account your program is accessing remote machine under is not logged in on the remote machine. What should Windows do? Actually, documentation for RegConnectRegistry, which is what OpenRemoteBaseKey calls internally, does not even list HKEY_CURRENT_USER as a permissible argument.

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.

Impersonation to get user HKEY_CURRENT_USER does not work?

I am attempting to Impersonate an administrator account from a LocalSystem Service in order to get data from administrators HKEY CURRENT USER registry - in order to impersonate I am using the codeproject code found at the following site written by Uwe Keim: Impersonator
My source code is as follows:
using (new Impersonator("user", ".", "pass"))
{
RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software\\CompanyName");
string sValue = rk.GetValue("Value", "").ToString();
rk2.Close();
}
My expectation was that sValue would be from the user/pass account (as I am impersonating it) but oddly enough it is still the sValue from the LocalSystem account where my service is runnning ...
Any clues on what I am doing wrong? Any help would be much appreciated.
Thanks,
I know this is an old thread but I recently came across the same issue (albeit from a C++ Windows service) and thought I'd share my findings, because many forums have asked the same question and none have left a satisfactory answer.
Basically, I've found two ways to approach this, though this is an answer more for C applications rather than .NET (I haven't tested with pinvoke but it may work).
Solution 1:
Instead of using RegOpenKey, use RegOpenCurrentUser() to get the key handle. Apparently, the reason RegOpenKey doesn't get the impersonated user's key is because HKEY_CURRENT_USER is cached in the running thread.
Solution 2:
RegDisablePredefinedCache(). This disables the cache mentioned above and lets subsequent calls to HKEY_CURRENT_USER be of the actual impersonated user. This is the solution I went with.
Hope this helps.
Everything I've read on the subject seems to indicate that impersonation should get you access to the HKEY_CurrentUser for the impersonated account. However, it could be a quirk in the .NET Registry implementation.
This is just a hunch, and an untested one at that, but have you considered using Registry.Users instead of Registry.CurrentUser?
You'll need to find the SID for the Administrator account, but you should be able to deduce that using Regedit
By default the HKEY_CURRENT_USER handle is cached on a process wide basis. So when you impersonate a user and then access the current user hive you will be accessing the hive of the user that started the process not the user being impersonated. This is true for all Win32 processes not just .Net. If you wish to disable this caching so that all current user calls go to the correct user hive under HKEY_USERS then you must call RegDisablePredefinedCache via pInvoke.
Be warned that if the user being impersonated has not had their profile loaded then any CurrentUser requests will be forwarded to the .DEFAULT user. So you may also need to call LoadUserProfile.
Disabling the handle caching will also cause a slight slowdown in all CurrentUser requests.
I'm guessing you're going to find that you're out of luck. It can't be done.
If applications were able to impersonate an Administrator account and write values to the Registry in Windows, it would present a huge security hole. My guess is that the Registry.CurrentUser property will ALWAYS reference the user running your application...whether or not you try impersonation or not.
EDIT
Turns out that I didn't read the implementation details of the Impersonator code you were using. Your problem could be something completely different.
Does your code refer to the Registry static class prior to your impersonation code being run? If so, that would be the problem. If you look at the Registry.CurrentUser property in Reflector, you'll see that it is set by the static constructor of the Registry object. Static constructors get called when the static object is first referenced.
In your case, if you're referencing the Registry object (whether it involves CurrentUser or not) the static constructor is being called which is setting CurrentUser to your original user...not the Impersonated account.

Categories