Access denied reading Perfmon counters from a remote machine (Asp.Net) - asp.net

I'm trying to create a simple Asp.Net page to read Perfmon counters from a remote machine.
When I run the page using the Visual Studio development web server all is well, however when I attempt to run the same page when its hosted on IIS I get an access denied error on the line that instantiates the Perfmon counter:
PerformanceCounter freeSpaceCounter = new PerformanceCounter("LogicalDisk", "Free Megabytes", "D:", "RemoteMachine12");
This is the exception I get:
Exception Details: System.ComponentModel.Win32Exception: Access is denied
I've tried using both anonymous access (with myself as the anonymous user) and Integrated Windows Authentication - both dont work. Clearly some other account is be used to read the PerfMon counters (like the ASPNET account). How do I get my page to access the PerfMon counters using my account rather than that account?

The problem you have here is that IIS runs under the context of a local account (by default). This local account doesn't exist on the remote machine, and so can't connect to get the performance counters. When you use the VS development web server it runs under your own local account and so everything works.
If you're in a domain environment you can configure the IIS application pool to run as a domain account with access to both machines, and everything will work, however you may want more control over this.
You could either use basic authentication, with the application configured for impersonation (or if you're using IIS7 having the pool configured to run under the authenticated account) or you impersonate just before you read the counter.
There are a couple of ways to impersonate - the safest is to configure IIS to use integrated authentication and then wrap the call up
PerformanceCounter freeSpaceCounter = null;
using (((WindowsIdentity)HttpContext.Current.User.Identity).Impersonate())
{
freeSpaceCounter = new PerformanceCounter("LogicalDisk",
"Free Megabytes", "D:", "RemoteMachine12");
}
If you don't want authentication then you'll have to configure the app pool, or hard code a username and password in your application - this should be the last resort, see KB306158

From MSDN:
To read performance counters in Windows Vista, Windows XP Professional x64 Edition, or Windows Server 2003, you must either be a member of the Performance Monitor Users group or have administrative privileges.

Related

Granting Permissions to Local User Account to Issue Custom Command to Windows Service from ASP.NET Web Application

CONTEXT
My client has an ASP.NET web application running in IIS 10 on Windows Server 2016. The web application needs to access files on network shares on different servers in a WORKGROUP environment. So, I created the same local user account on all servers, set the password to all the local user accounts to be the same, granted said user with full control permissions to the network shares, and reconfigured the IIS application pool to run under the identity of the aforementioned local user account. There is also a custom Windows service running under the same local user account for the same reason: to access files on remote network shares. All of this works fine. The web application and the Windows service can successfully access files from the network shares residing on servers other than the server on which IIS and the custom Windows service are both running.
ISSUE
However, there is a feature in the web application when an authorized user modifies a particular validation matrix record, it triggers a custom command sent to the aforementioned Windows service to cause the service to update its in-memory copy of the validation matrix. This worked fine when the IIS application pool was running under the built-in ApplicationPoolIdentity which apparently has permissions to interact with Windows services. But, the feature fails when the IIS application pool is running under the identity of the aforementioned local user account. The message in the exception is: Cannot open {SERVICE_NAME} service on computer '.'. Again, the Windows service and IIS are running on the same server. And recall that the Windows service is running under the same local user account as the IIS application pool identity.
QUESTION
How do I grant permissions to the local user account to allow said account the ability to issue the custom command to the Windows service from within the ASP.NET web application?
RESOLUTION ATTEMPTS
I've tried using subinacl.exe in an attempt to grant the necessary access but never got it to do anything other than to indicate Done 0, Modified 0, Failed 0, Syntax errors 0. I'm using version 4.2.1.1604 and executing it from an Administrative Command Prompt. The syntax I used was:
subinacl /service customServiceName /grant=localUserAccount
and the result is below
+service customServiceName
/grant=localUserAccount
Elapsed Time: 00 00:00:00
Done: 0, Modified 0, Failed 0, Syntax errors 0
I also tried /grant=localUserAccount=U and /grant=localUserAccount=F but to no avail ... same results as shown above.
I admittedly am not familiar with subinacl.exe and I saw somewhere that someone indicated earlier versions of subinacl.exe are buggy and suggested using version 5.2.3790.1180 which I cannot find. Result: failed.
I have added the local user account to the Administrators group on the server where IIS and the Windows service are running. Result: failed. CORRECTION 02/13/2023: This succeeded but required a server reboot for it to take effect. To be clear, I do NOT want to permanently add this user to the Administrators group. This was simply a test. As far as the server reboot being required for this to take effect is concerned, I tried recycling the application pool in IIS, restarting the Windows service of interest, and restarting the World Wide Web Publishing Service but no joy. Only a server reboot caused the addition of the local user account to the Administrators group to take effect from the standpoint of said local user having permissions to send a custom command to the Windows service from within the web application. I absolutely am inclined to believe that there is a better way to achieve the desired end without adding the local user account to the Administrators group. Surely someone else before me has encountered this and solved it.
The local user account is already set up in the Local Security Policy with the ability to "Log on as a service".
I have reconfigured the IIS application pool identity to NETWORK SERVICE and granted NETWORK SERVICE full control permissions to the network shares (which are on a different server in a WORKGROUP environment, not a domain environment). In this configuration, the feature to update the Windows service works, but access to the network shares is denied ... likely because NETWORK SERVICE is a built-in local account [with no password?? not sure on this] and does not behave the same as a "regular" local user account.
So, I have a catch-22 that has me stumped. I would be grateful for any insight on this dilemma.
Cheers!

The pipe name could not be obtained for the pipe URI: Access is denied

I am getting an "Access is denied" error on a 2012 R2 server when my web app on that server tries to access a self-hosted WCF service on that server using named pipes.
I do not have this issue on my development machine (Win 7). I can access the WCF service via the client test app on both the server and my development machine.
If I enable ASP.NET Impersonation on the web site using a user account that has full control permissions to the install folder for the WCF service, then the error goes away. I do not want to use impersonation since I understand it has significant performance penalties (not to mention security issues) and the WCF service is called for every user input during a session.
The strange thing is... If I set the app pool to run as either the user with rights to the service folder as described above or as a user with admin privileges, then I still get the error if ASP.NET Impersonation is disabled. The error will go away only after I enable ASP.NET Impersonation on the web site.
I do not have access to the source for the WCF service.
In this case, the web app was located on the D:\ drive and the Anonymous Authentication user (IUSR) did not have RX permissions to the web app location.
Note that if you are using Windows Authentication, then the same issue occurs if the Windows Authenticated user does not have RX permissions to the location of the web app.
The problem was resolved once I gave the authenticated user the proper permission.
Sometimes the solution really is just plain simple...
"Ain't got no gas in it" - Slingblade.

Can't get rid off "Login failed for user IIS APPPOOL\NETWORKSERVICE"

I'm trying to access a sql server database from an ASP NET app configured to work with IIS.
I have several questions now,
1) Authentication in IIS: I need to know if my authentication settings for the site are ok:
I tried with Windows Authentication set to Disabled, but the problem continues.
2) Are the settings for the user NT AUTHORITY\Sericio de red well configured? ("Servicio de red" means Network Service)
3) When I added the login for network service, I only found "Servicio de red", I guess it's the equivalent for NetworkService, I'm I right?, My windows 7 ultimate is an spanish version, I just changed the windows interface by using a windows upgrade to make it appear in english. Is there a problem with it?, I guess it's right because the access to the database is being done through the IIS APPPOOL\Servicio de red user.
My DefaultAppPool identity is set to to AppPoolIdentity
If you want to see what I have tried, see this thread.
The whole project, along with a backup of the database I'm using can be found here, called MyServiceSolutionInIIS
What I'm trying is to build a WCF Data Service that offers information that comes from an entity data model generated from a sql server database. This service will be used by a WPF App as a client.
I'd like to avoid creating a user for it, I think it can be done with the App Pool
Okay so the way this works is, whatever application pool your endpoint is running under passes its credentials to the SQL Server. So, you have two options:
Run the default application pool under NetworkService, or;
Use SQL Authentication when connecting with your web service to the SQL Server.
Honestly, the latter is the most common, but in your situation you may be just fine by changing the default application pool to run under NetworkService.
This has nothing to do with the authentication you've chosen (well, mostly nothing.. you can control which credentials anonymous users run under). Every website runs in an app pool, and this app pool has an AppPoolIdentity.
I'm a little confused as to why it would be claiming it's IIS AppPool\NetworkService, since NetworkService should be NT AUTHORITY\NetworkService, or IIS AppPool\MyAspService or IIS AppPool\DefaultAppPool.
There is a lot more information on App Pool Identities here:
http://www.iis.net/learn/manage/configuring-security/application-pool-identities
Note: There is a bug in IIS 7.5 (the version of IIS that comes with Windows 7 and Windows Server 2008 R2) that sometimes causes authentication problems with AppPoolIdentities if the users password changes (say, if you have mandatory password change policies). There is a hotfix here:
http://support.microsoft.com/kb/2545850/en-us
More info here:
IIS application using application pool identity loses primary token?
There so many scenarios in which this issue occurs.
First thing you need to clear if you are using windows authentication and you are not mentioning any username password in your connection string then:
What happens when you run your code through localhost: when you run your wcf test client from localhost, it will be able to communicate to database as local debug mode application is calling database by your account's service. So it has access to database because devenv.exe is running under your user account.
But when you deploy your web service in IIS. Now understand this service runs under IIS not under your account. So you need to assign access rights to IIS service to access the sql server for windows authentication. Here your web service would not be able to communicate to the SQL server because of access rights issue and Login Failed for user_______ (here your user will come)
So if you are using windows authentication to connect your database, you just have to change the IIS Application pool settings. You need to change IIS Application pool's identity to:
local System (for single windows user).
Network Service (for intranet users or domain users)
Below are the Steps for windows authentication WCF:
•Open IIS (windows+R (run) then type inetmgr, then click ok)
•double click your PC name under Connections
•Click Application Pools
•Select your app pool (DefaultAppPool)
•Then under actions on the right click Advanced Settings:
•Go to Process Model section and
•click on Identity.
•Now select LocalSystem (for single windows authentication user).
or select Network Service (for Intranet users)
Now open your sql server management studio: open run-> then type ssms then press ok in ssms, login using your windows authentication account. open security tab expand logins tab then you will be able to view your account.
Now open properties of your account go to userMapping then select the database you want to connect then check the role membership services you want to use for the selected database click ok. (For network services i.e. intranet users you need to configure above settings for NT AUTHORITY\SYSTEM user too)
add Trusted_Connection=True; property in your connection string. Save it & deploy the web service. Restart app pool.
you will be able to connect the database now.

How can I set the user running the service?

I created a MVC4 web application on my laptop using localdb with a mdf. file. I then exported the project to my desktop, and then I copypasted these files over to my webserver on my Win2k12 running IIS.
After copying it I created the tables on the MSSQL Express 2012 server that runs on the same Win2k12 server, and modified web.conf in my project to target the server and not the mdf file.
And here is where it all stops, I get the following error when I try to send data (that should communicate with the sql server, browsing pages is fine as long as it does not try to talk to the sql server):
Cannot open database "mc.foo.net" requested by the login. The login failed.
Login failed for user 'IIS APPPOOL\mc.foo.net'.
And I'm guessing the user IIS APPOOL is something inherited from my laptop, I don't have this user on thw Win2k12 server. How can I change that? And to what? I have several users (from Security of the server in SQL Server Manager):
NT AUTHORITY\SYSTEM
NT Service\MSSQLSERVER
NT SERVICE\SQLWriter
NT SERVICE\Winmgmt
In addition to my domain administrators. How can I fix this?
You can easily change the application pool identity in IIS Manager.
On the target application pool (under Root/application pools), select Advanced Settings. The is a Category Process Model, where you can specify pool's identity.
Built-in account allow you to use Network Service/Local System/... whereas Custom allow you to specify a domain or local user. That's all !
It's not recommended to give too many privileges on the application pool. This can hurt security of your application and can be sometimes painful to manage. So, I would highly suggest you to use sql authentication for your database and to encrypt connection string.
Your problem seems like the user doesn't have rights on the DB Server.
There are multiple ways to go around this.
If you are connecting through integrated security to the DB... Change that to a local SQL server or a domain username and password.
Give your appPool account dataReader or dataWriter access (Not recommended for production).

SQL Server and windows authentication in IIS7

I'm trying to get an ASP.NET website running on Vista (IIS7), using SQL Server and Windows Authentication. No matter what I do, when I connect to the database, I get the exception:
SqlException was unhandled
Login failed for user 'MyDomain\MachineName$'.
It doesn't seem to matter what settings I apply, I cannot get IIS7 to pass through my Windows login credentials.
Extra details:
Both the SQL Server and my local machine are on ActiveDirectory
Vista Enterprise, IIS7
SQL Server 2005
Anonymous Authentication disabled, Windows Authentication enabled
Impersonation on/off makes no difference
All Identities (NetworkService, LocalSystem, etc) give the same result
Classic and integrated pipelines give the same result
Help!
Impersonation on/off makes all the difference, when properly configured. What you want is caled 'constrained delegation' and you need to configure IIS and ASP for it:
How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0
Configure ASP.NET Impersonation Authentication (IIS 7)
Configuring Servers for Delegation
By default, the IIS server is not allowed to impersonate you towards the SQL Server. There's an MSDN article on how to configure it. The configuration process is complex and error prone.
If your production ISS and SQL Server run on different servers, you'll need a domain admin to configure impersonation trust between the two servers. This is typically a no-go in a big organization.
In addition to not being deployed by normal admins, impersonation also prevents users from sharing their connections in the SQL connection pool. This results in a very noticeable performance penalty for even small (5+ users) websites.
Did you try to create a new user account for your application, grant it the appropriate rights on the Sql Server, and then set the application pool to run under this new account?
This is what I usually do, and it works. I'm not running my application under NetworkService, LocalSystem or other builtin accounts.
Does your connection string contain Integrated Security=SSPI?
Have you switched the asp.net context to be a domain user as well?
Here is an MSDN article on this topic
http://msdn.microsoft.com/en-us/library/2xzyzb0f.aspx

Resources