writing to Windows registry from intranet app - c#

I have an intranet web application where encrypted connection string is stored in Windows registry (connection string is shared by some other apps). Application is hosted on a Windows 2012 server. In development/test environments (not production) I want to be able to modify this key so I can switch to different databases.
I do not seem to be able to write to it, I keep getting different errors depending on how I approach it:
string sKeyValue = "SOFTWARE\\SomeProject\\SomeApp";
RegistryKey rk;
rk = Registry.LocalMachine.OpenSubKey(sKeyValue, true); // Requested registry access is not allowed.
Tried:
RegistryPermission p = new RegistryPermission(RegistryPermissionAccess.AllAccess, sKeyValue);
p.Assert();
also
RegistrySecurity rs = new RegistrySecurity();
RegistryKey key = Registry.LocalMachine;
rs = key.GetAccessControl();
string sUser = #"domain\userid";
rs.AddAccessRule(new RegistryAccessRule(sUser, RegistryRights.WriteKey, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow));
key.SetAccessControl(rs); //Exception: "Attempted to perform an unauthorized operation."

Allowing write access to the registry from a web app is just a bad idea all around. Automatically setting permissions via web code is dangerous and requires the code to have too-elevated privileges.
It's better to give all your web apps permission to read from the same web.config file, then get the shared setting something like what is described here.
IIS web.config - same file for multiple websites

Related

How to write in registry from ASP.NET App in IIS?

I try to write in the Registry.LocalMachine from an asp.net app. I use the following code, and it works on my development machine :
string value = "some value";
RegistryKey clefDeRegistre = Registry.LocalMachine;
RegistryKey clefTapi = clefDeRegistre.OpenSubKey(#"SOFTWARE\SomeEditor\MySubKey", true);
if (clefTapi != null)
{
clefTapi.SetValue("Options", value);
}
But when I try this on my server (Windows Server 2008 R2), it doesn't work.
With the default app pool settings, I received a security exception when trying to write in the registry. So I changed the app pool identity to LocalSystem.
Now I don't receive any exception, but the key isn't modified.
It looks like a problem with Registry Virtualization, but I don't understand how I can disable it.
If your application pool is in 32 bit mode, then the key goes to SOFTWARE\Wow6432Node branch.

Sharing app.config

I've got 2 applications:
Windows Service (with HTTP listener for config website & api)
Control Utility (WPF app)
The requirements of the control utility are pretty straightforward:
Start / stop service
Launch browser pointing to website (e.g. http://local:5555)
Looking for a Windows Service called "MyService", retrieve its status and start it when needed is pretty simple. However, how do I launch the browser with the correct link? The port which the HTTP listener is listening for is configurable inside the app.config of my Windows Service application and there is no possibility to discover the listener. Can a app.config be shared between 2 applications?
I know ConfigurationManager has OpenExeConfiguration(), but this causes other problems:
I have to know the path where the Windows Service is installed
Reading the configuration may cause a read lock
If the config file is encrypted, I have to know the key
Are there any other solutions to achieve this?
You could use the registry for exchanging data.
// Create a Subkey
RegistryKey newKey = Registry.CurrentUser.CreateSubKey("SOFTWARE\\SuperSoft\\App");
// Write Values to the Subkey
newKey.SetValue("Value1", "Content1");
newKey.SetValue("Value2", "Content2");
// read Values from the Subkey
if (SubKeyExist("SOFTWARE\\SuperSoft\\App"))
{
RegistryKey myKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\SuperSoft\\App");
string firstApp = (string)myKey.GetValue("Value1");
string secondApp = (string)myKey.GetValue("Value2");
}

DirectoryEntry IIS access permission

I have one console application which list website binding in IIS
using (var directoryEntry = new DirectoryEntry("IIS://localhost/w3svc/" + GetWebSiteId())) {
var bindings = directoryEntry.Properties["ServerBindings"];
}
I call this console application from ASP.NET via process
var process = new Process {
StartInfo = new ProcessStartInfo {
FileName = "c:/app.exe",
Arguments = "check",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
Everything works fine on development machine under Widows 7 / IIS 7.5, but when i test on Windows 2012 / IIS 8 im getting "Access is denied" error.
Error log
"System.Runtime.InteropServices.COMException (0x80070005): Access is denied.
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_IsContainer()
at System.DirectoryServices.DirectoryEntries.ChildEnumerator..ctor(DirectoryEntry container)
at System.DirectoryServices.DirectoryEntries.GetEnumerator()
at IISSubdomainManagement.Program.GetWebSiteId()
at IISSubdomainManagement.Program.TotalBindings()
at IISSubdomainManagement.Program.Main(String[] args)"
p.s Application pool identity is "ApplicationPoolIdentity"
I forget to mention, my console app works fine on my server when I run it from CMD
You need to give permission to the IUSR account to access and execute C:\app.exe. This link should provide you with the necessary information to find the right account.
You have probably granted the permission to 'ApplicationPoolIdentity' rather than to the virtual account that actually corresponds to that Application Pool. Read through the Microsoft's description or search online for virtual identity IIS, etc.
On your development machine, you probably have some sort of Full Admin rights, so it is not as restricted.
If you still have problems after that, I would recommend replicating the error with a Process Monitor running, so you can see exactly what process is accessing which resource with which identity. However, I would recommend replicating the issue on your development machine rather than running Process Monitor on the production. It takes a little bit of learning to be able to run it efficiently.
In IIS 7/8 go Control Panel / Program And Features / Turn Windows features on or off, and check all items from: Web Managment Tools, (it's include: IIS Managment Service, II 6 Managment Compatibility)
This Solution worked for me ==>
http://blogs.msdn.com/b/jpsanders/archive/2009/05/13/iis-7-adsi-error-system-runtime-interopservices-comexception-0x80005000-unknown-error-0x80005000.aspx?CommentPosted=true#commentmessage

Way to write on registry location

work on C# window application.I want to write on registry.i know how to write on registry.I use bellow syntax to write on registry.
Microsoft.Win32.RegistryKey key;
key = Microsoft.Win32.Registry.CurrentUser.cre.CreateSubKey("asb");
key.SetValue("asb", "Isabella");
key.Close();
But problem is i fail to write on specified location .i want to write on bellow location
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
On this location want to add string value="abc" and ValueData="efd"
If have any query plz ask.thanks in advance.
For HKCU:
string keyName = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
RegistryKey rk = Registry.CurrentUser.OpenSubKey(keyName, true);
rk.SetValue("abc", "efd");
rk.Close();
For HKLM you need to do it with administrative privileges. That requires adding a manifest to your program to invoke the UAC prompt on Vista or Win7.
Writing to HKEY_LOCAL_MACHINE requires administrative privileges. And if you're running on Windows Vista or 7, it also requires process elevation, lest you run afoul of UAC (User Account Control).
The best thing is only to write to this registry key during installation (where you will have full administrative privileges). You should only read from it once your application is installed.
Save all regular settings under HKEY_CURRENT_USER. Use the Registry.CurrentUser field to do that. Or, better yet, abandon the registry altogether and save your application's settings in a config file. Visual Studio has built-in support for this, it's very simple to do from C#. The registry is no longer the recommended way of saving application state.
RegistryKey reg = Registry.LocalMachine.
OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Run", true);
// set value of "abc" to "efd"
reg.SetValue("abc", "efd", RegistryValueKind.DWord);
// get value of "abc"; return 0 if value not found
string value = (string)reg.GetValue("abc", "0");

Cannot Write to the Registry under HKEY_LOCAL_MACHINE\Software

I'm writing an application that needs to create a special user account hidden from login screens and the Control Panel users applet. By writing a DWORD value of 0 with the user name to the registry key below, I'm able to accomplish this goal:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Winlogon\SpecialAccounts\UserList
The problem is that under Windows 7 with UAC on, no matter what I try, I cannot programmatically write a value to the key above.
It is my understanding that writing to certain keys this is not allowed on Windows 7 with UAC on, unless you are running with Administrative privileges. I've added an application manifest requestedExecutionLevel level="requireAdministrator" uiAccess="false", I accept the UAC prompt when my program is run, my account is a member of Administrators, yet I am still unable to write to the above registry key.
What more do I need to do? How is it possible, in any application configuration, to write keys and values under HKEY_LOCAL_MACHINE\SOFTWARE?
Further information ... When my program runs, no errors are thrown and it seems to write values. My guess is that Windows is virtualizing the location to which I am writing. I need to write to the actual location, not a virtual one, if I am to hide this special user account.
Probably the program runs as 32-bit program on the 64-bit operation system? In the case I recommend you to search the values which you created under Wow6432Node subkey of the HKEY_LOCAL_MACHINE\SOFTWARE.
You can read more about such kind of virtualization here. You can use KEY_WOW64_32KEY flag in some API to be able to work with full registry without virtualization.
Write Value to Registry
string user = Environment.UserDomainName + "\\" + Environment.UserName;
RegistrySecurity rs = new RegistrySecurity();
rs.AddAccessRule(new RegistryAccessRule(user,
RegistryRights.WriteKey | RegistryRights.ChangePermissions,
InheritanceFlags.None, PropagationFlags.None, AccessControlType.Deny));
RegistryKey rk = null;
try
{
rk = Registry.CurrentUser.CreateSubKey("SOFTWARE\\TEST",
RegistryKeyPermissionCheck.Default, rs);
rk.SetValue("NAME", "IROSH);
rk.SetValue("FROM", "SRI LANKA");
}
This could have something to do with the redirection they added in Vista. I would be curious if you tried to read that registry value from your code, if you would get back the value you were expecting. You may also want to fire up RegMon to see if you can see where the redirection may be forcing you.
RegistryKey rk = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Run",true);
rk.SetValue("Name", "Value");

Categories