Working with Windows Service and Web Service together is nothing less than fun, especially when you are not an ASP.NET expert. Like many native developers I have my own challenges with words like managed, web service and web applications!
I was debugging a production down. My customer had a Web application which was communicating with a Windows Service. Whenever the web application use to start it use to check if Windows Service is running, if not it would attempt to start the Windows Service. This web application was failing to start the Windows Service. Web applications have their own way of reporting the failure, we got back Cannot open the service control manager on computer “.”
This web application use to work fine when a domain administrator or a user who is administrator on the IIS server launches the web application. It was domain users who were getting these errors.
We later figured out that the Web application is written in C# and it was using .Net 2.0. Also, it was using integrated authentication (Windows Authentication) this means that the identity in which the user is logged in on the client computer (where the Internet Explorer is running) will be delegated to the ASP.NET application to do any kind of operation. Also, .NET 2.0 has impersonation true by default. The above information is important it tell that it is actually domain user who will attempt to start the Windows Service.
Windows service is a securable object in Windows. By default, only Administrators can start and stop a Windows Service. It is determine by the DACLs present on the service. This pretty much tells that why the domain users were not able to start the service.
I printed the DACL of a Windows Service
C:\Windows\system32>sc sdshow Service1
The heighted ACE is grants access to the administrators. You can notice by default there is no ACE present for the authenticated user. The DACL of the service is given while the service is being created. During installation you can provide a custom DACL to your service depending on your needs.
Follow these steps to change the DACL of a Windows Service such that it grants permissions to authenticated users as well. Change the name of the service from Service1 to your service.
1) Login the Server as Administrator and run CMD.
2) SC SDSHOW Service1 > OldSDofService1.txt
3) The output in the OldSDofService1.txt should look like : D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)
4) Change it to D:(A;;CCLCRPRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU) and save it to NewSDofService1.txt. Highlighted text shows the changed part of SDDL.
5) In the command prompt run SC SDSET Service1 D:(A;;CCLCRPRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)
6) Do SC SDSHOW Service1 and compare the output, you should see the newly set string.
Once new DACLs are applied authenticated users can start and stop the windows service. That means a web application which has an identity of domain user (authenticated user) can operate on the Windows Service.
This problem is not related with code of the Web Application and Windows Service. It is more dictated by the environment. Access on a Windows Service is more to do with setup of Active Directory and policies and permissions in the domain.
We cannot foresee this problem and there for cannot fix it in the code. However, it is possible to modify the DACL of the SCM during installation; so if you are certain about who all are going to access your service you can provide appropriate DACLs.
I did not discuss about deciphering the security descriptor string. If you have difficulties you can refer to Security Descriptor Definition Language