Guest Account Restrictions - c#

I am working on a project where I have to validate the Platform for Intel Atom processor and Windows 7 OS.
I have Used:
ManagementClass mgmt = new ManagementClass("Win32_Processor");
//for Intel Atom, "Win32_OperatingSystem" for Win 7 OS
Now, This Logic is working fine when login as Admin or Standard user, But When login as Guest User I am getting System.UnauthorizedAccessException in method:
void ThrowExceptionForHRInternal(Int32, IntPtr)
description: Access is denied
Is there any restriction for the Guest Account to fetch Platform details?

Yes they are.
You will not get around this without dcom changes or impersonation. I am not able to test it right now but I am quite sure the Environment class will throw a exception also.
You simply have restricted access as guest and that included most wmi access and most environment access that goes further than username. And impersonation is a bad thing in this context that I wouldn't do. I am not even sure that it will work for you in that case or just throws another Exception.

Related

Permissions required to retrieve local group members with ADSI

Using ADSI I can query the members of the local Administrator group on a given computer by doing (for example in PowerShell) :
([ADSI]"WinNT://computer-name/Administrators,Group").Invoke("members")
To do this, as far as I can tell, the user running the PowerShell script requires Administrator privileges on the target machine - that is, the user needs to be directly on indirectly in the local administrator group of computer-name (eg. by being a member of "Domain Admins").
This surprised me because a non-administrator account who can login to computer-name (eg. a user that's part of "Domain Users" and nothing else) can open the local users & groups application, and view the members of the local administrator group. No specific rights are required when doing it manually, yet ADSI seems to require it.
So my questions are:
Is it correct that using ADSI you need Administrator rights to access this information, or am I doing something wrong?
Is there a different approach to programmatically obtain this information, which requires less privileges than an Administrator account ? (If there are solutions that are not available in PowerShell that's fine, my targets are C#/.NET Core )
Please note I want to run this remotely on other workstations - not just on the local workstation.
ADSI is built on top of WMI. By default, only the local Administrators group is allowed to make remote WMI calls and read a computers local directory data.
You can change the permissions on the OS by going into Computer Management (local) -> Services and Applications -> WMI Control. Right click on WMI Control and choose Properties.
I've only experimented with allowing all reads, which you can set on the root folder. I did some research and you may be able to restrict this to just LDAP. On the Security tab drill down to Root -> directory -> LDAP. You'll want to adjust permissions on the LDAP entry (or maybe more?). The key permission is Remote Enable.
Update
To query WMI directly from PowerShell.
Remote WMI over PowerShell: https://learn.microsoft.com/en-us/windows/win32/wmisdk/connecting-to-wmi-on-a-remote-computer.
Custom PowerShell method for listing remote group membership through WMI: https://gallery.technet.microsoft.com/scriptcenter/List-local-group-members-c25dbcc4
I think your ADSI approach should work, at least when executed locally.
I used a c# snippet I grabbed from this SO answer: https://stackoverflow.com/a/8192062/3374994.
To test whether it could run from regular user permissions, I used
Runas /user:regularuser GetLocalUsers.exe.
I believe this shows that an ADSI approach would not necessarily require elevated privileges.
However, was your intention to run the code remotely?
var path = string.Format("WinNT://{0},computer", Environment.MachineName);
using (var computerEntry = new DirectoryEntry(path))
{
var userNames = from DirectoryEntry childEntry in computerEntry.Children
where childEntry.SchemaClassName == "User"
select childEntry.Name;
foreach (var name in userNames)
Console.WriteLine(name);
}

Requested registry allow access without security leaks

Right now i am using an web application with code to read from and write to the registry. While debugging in Visual studio everything went fine but on the online test server it didn't run. the error exception message i am getting is:
System.Security.SecurityException: Requested registry access is not
allowed.
This is the code i am using:
private RegistryKey GetWritableBaseRegistryKey(string extendedPath)
{
var path = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
return RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default).OpenSubKey($"{path}\\{extendedPath}", true);
}
The sollutions i found where:
Solution 1
you will not be able to set AppPoolIdentity to a specific group, but
you can
create a local user (compmgmt.msc)
add the user to the administrator group (compmgmt.msc)
Set the application pool to run under that user, under Advanced Settings.
Obviously you know this is a very bad idea from a security
perspective, and should never ever ever be performed on a forward
facing server.
source
Solution 2
Create a separate console application to run the service in admin
modus so you could access the registry. This solution was performance
heavy because you need to run 2 separate applications.
Solution 3
Use this code to allow access to the registry.
RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.AllAccess, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall");
perm1.Demand();
Or this code
RegistrySecurity rs = new RegistrySecurity();
string currentUserStr = Environment.UserDomainName + "\\" + Environment.UserName;
RegistryAccessRule accessRule = new RegistryAccessRule(currentUserStr, RegistryRights.WriteKey | RegistryRights.ReadKey | RegistryRights.Delete | RegistryRights.FullControl, AccessControlType.Allow);
rs.AddAccessRule(accessRule);
But these didn't work on the server however while debugging in visual studio the code ran fine.
In order for the web application to access the registry it must have sufficient permission. Consequently Solution 1 is the only one likely to work. It describes setting the web sites application pool to a user in the local administrators group. Its misses the steps about actually setting your IIS web site to use the newly created App Pool, which is why it might not work for you.
The technical process of reading a restricted registry, especially the application Uninstall registry key, inside a web server is really unlikely to be useful to you. Of what possible use is allowing a web server to access the servers own Application uninstall list going to be ?
I suspect you intend to open that registry key on the client's PC (my speculation) which is not going to be possible.

Cannot write the event log when the app runs on windows server 2012 from server 2008

I upgrade my app which worked fine on Windows Server 2008(32 bit) from framework 3.5 to 4.5 for Windows Server 2012(64 bit). In the app, there is third party component runs on 32 bit. We cannot upgrade it because the supplier has no plans to update it. Therefore my app platform target is set for any CPU but Prefer 32-bit on my project property. All function is work except writing the event log. Would anyone provide suggestion to deal with this issue? Thank in advance.
There is my code to write the event log.
private static void RecordEventLog(string sMessage, EventLogEntryType ErrorType)
{
string source = "Testing App";
string logName = "Application";
string machineName = ".";
if (!EventLog.SourceExists(source, machineName))
{
EventSourceCreationData sourceData = new EventSourceCreationData(source, logName);
sourceData.MachineName = machineName;
EventLog.CreateEventSource(sourceData);
}
new EventLog(logName, machineName, source).WriteEntry(sMessage, ErrorType);
}
The problem may be the rights to create the event source - I can't see why 32 vs 64-bit would make a difference. You may have to run the app with admin privileges (at least the first time) to create the event source.
From MSDN:
To create an event source in Windows Vista and later or Windows Server
2003, you must have administrative privileges.
The reason for this requirement is that all event logs, including
security, must be searched to determine whether the event source is
unique. Starting with Windows Vista, users do not have permission to
access the security log; therefore, a SecurityException is thrown.
In Windows Vista and later, User Account Control (UAC) determines the
privileges of a user. If you are a member of the Built-in
Administrators group, you are assigned two run-time access tokens: a
standard user access token and an administrator access token. By
default, you are in the standard user role. To execute the code that
accesses the security log, you must first elevate your privileges from
standard user to administrator. You can do this when you start an
application by right-clicking the application icon and indicating that
you want to run as an administrator.

Accessing Network Path in Windows Service C#

I have developed a windows service using local system as Account. I have used
network path of file
FileInfo fi = new FileInfo(#"\\epm-server\penDocuments_LabMeds\" + Convert.ToString(dr["mrn"]) + "\\SyncedXML\\" + Convert.ToString(dr["xmlfile"]));
if (!fi.Exists)
boolFileNotFound = true;
A dynamic path of a file that is built from database.
It works fine when I run Windows Service in Debug Mode, but when I install it then fileNotExists returns TRUE always like the file doesnt exist but infact it does exist.
This is bugging me a lot now. Kindly help me why its not working. Its a server path. Its getting opened in my PC.
Thanks
Did you notice the double backslashes in front and after SyncedXML (\\SyncedXML\\)?
This is probably the cause of your error.
Additionally I'd use string.Format in such cases to reduce the inadvertently addition of unwanted characters:
var path = string.Format(#"\\epm-server\penDocuments_LabMeds\{0}\SyncedXML\{1}", dr[mrn], dr[xmlfile]);
var fi = new FileInfo(path);
Edit:
If it's permission-related, then it's very likely that your local system account (in whose context the service is running) isn't allowed to access the epm-server.
The path is accessible if you're opening it directly or if you're running the service in debug mode as this is happening in your user context (e.g. YOURDOMAIN\vickyshazad), and you're allowed to access the ressource, whereas NT AUTHORITY\SYSTEM is not.
It's usually a good practise to have a special service account for your developed windows service and grant this user only and exactly the required permissions (least privilege). Maybe ask your system administrator for a service user.
Local System (NT AUTHORITY\SYSTEM) is a highly privileged account that's not recommended to use in general (see MSDN).
Most services do not need such a high privilege level. If your service does not need these privileges, and it is not an interactive service, consider using the LocalService account or the NetworkService account.

How to get registry write permissions in C#

I'm trying to write to the windows registry at HKEY_CURRENT_USER\Software\appname however I keep getting a permissions error when I attempt to write to the key, I have added the following to my assembly:
[assembly: RegistryPermissionAttribute(SecurityAction.RequestMinimum, Write = #"HKEY_CURRENT_USER\\Software")]
but this has not resolved the issue, is there something else that I should be doing?
I don't suppose it's something as simple as you having opened the key without specifying that you want write access? The OpenSubKey(string) method only gives read-only access.
The RegistryPermissionAttribute is part of the Code Access Security aka CAS, this is a permission system which checks the permission you have inside of the .NET framework, these permissions are defined by the security policy. There are 4 security policies:
Enterprise - policy for a family of machines that are part of an Active Directory installation.
Machine - policy for the current machine.
User - policy for the logged on user.
AppDomain - policy for the executing application domain.
The first 3 are configured in the configuration screen in the .NET Configuration tool, and the last is configured at runtime.
The reason why I explain this first is because the RegistryPermissionAttribute only checks your .NET permissions, it does not check the Operating System permissions.
You could use the System.Security.AccessControl to check the operating system permissions, but to get the permissions you'll probably need to either elevate or impersonate.
Make sure the app runs using the user-account that has enough rights to access the registry.
I don't see an answer or resolution here. I found this question when searching for something else.
The one thing I think that may be needed is that you need to be running as administrator if you're running from the exe. If you're running from VS you'll need to make sure that VS is running as administrator. VS will show "(Administrator) in the window title if it is.
This works for me. With key already there and without it. Without any special assembly attributes.
using System;
using Microsoft.Win32;
namespace WriteToRegistry {
class Program {
static void Main(string[] args) {
const string csRootKey = #"Software\MyCompany\Test";
using (RegistryKey loRegistryKey = Registry.CurrentUser.CreateSubKey(csRootKey)) {
if (loRegistryKey == null)
throw new InvalidOperationException("Could not create sub key " + csRootKey);
loRegistryKey.SetValue("CurrentTime", DateTime.Now.ToString(), RegistryValueKind.String);
}
}
}
}
EDIT: After rereading the question it seems that the problem could be OS permissions.

Categories

Resources