Can't stop or start service from client app ("access is denied") RRS feed

  • Question

  • Hi,

    Quick question for all you Vista gurus out there.

    We have a service (running as SYSTEM) and we need to be able to stop and start it from our client application, which is running as a standard user. Is this possible? Our app was designed originally to run as administrator, but in order to get Vista certification we can't have it demand administrator access () so I'm trying to get it to run with the "asInvoker" access instead. But when I do that it can't access the service via the ServiceController. When we call serviceController.Stop() we get "InvalidOperationException: cannot open service on computer '.' --> Win32Exception: access is denied". The "Stop()" method is calling the "GetServiceHandle()" method, and that's the call that is throwing the exception.

    How do I solve this problem?



    Thursday, January 18, 2007 1:28 AM

All replies

  • Phil,

    I am only familiar with the C APIs, but hopefully you will be able to translate this into what you need.  In the code which installs your service, after calling CreateService() you need to use an API sequence such as QueryServiceObjectSecurity(), GetSecurityDescriptorDacl(), AllocateAndInitializeSid(), SetEntriesInAcl(), SetSecurityDescriptorDacl(), and SetServiceObjectSecurity() to give SERVICE_START and SERVICE_STOP access to your service to the appropriate group for your users.  When your code wants to start or stop the service, it can use OpenSCManager() with a desired access of SC_MANAGER_CONNECT and OpenService() with a desired access of either SERVICE_START or SERVICE_STOP as appropriate before calling StartService() or ControlService().

    Thursday, January 18, 2007 10:00 PM
  • Eek.  That seems like a lot of hoops to jump through, although maybe there are .NET counterparts to some of those calls. Part of the problem is that I just want to give everybody access. I can't know in advance what the user's group/domain is. Do I just give permission to the "Everyone" group, or set the ACL to null in that case? Security is definitely not something I really understand right now... seems like this ought to be a lot simpler. Anyway, thanks for the info!


    Friday, January 19, 2007 11:13 PM
  • You're stuck - you have have enough rights to control services, and ordinary users don't have those rights. I find it hard to believe that you can't request admin privileges in a program because of the Vista certification - I'd like to see where it says that because I can't find it.
    Saturday, January 20, 2007 3:54 PM

    The very first test case we're required to pass for Vista certification states that each application needs a manifest defining it's level of execution. It also says:

    Each manifest must have requestedExecutionLevel tag that is defined with the appropriate level of execution that is required for that executable. Levels of execution are: level=”asInvoker”, level=”requireAdministrator” and level=”highestAvailable”.





    The application’s main executable “requestedExecutionLevel” tag must have level=”asInvoker” in order to pass this test case. That means that the application’s main executable itself must be able to be run as Least-Privilege.


    There is this exception though:


    Any application that is required to run as an administrator or requires an elevated privilege to run properly must receive a waiver from Microsoft in order to pass this test case. In this case the “requiredExecutionLevel” tag must be set to “requireAdministrator” or “highestAvailable”.


    I don't know if we can get a waiver for this though. It would be great if we could because then I wouldn't have to jump through all these hoops! If anyone from Microsoft can comment on what kinds of reasons are acceptable for a waiver I'd love to hear it.



    Wednesday, January 31, 2007 1:28 AM
  • The following article is a "best practice" with regards to service DACLs.
    By default, administrative rights are required for most service control operations, but this can be changed.
    You can test your SDDL from an elevated command prompt with sc sdset <SDDL> <service name>

    Your install can convert the SDDL to a security descriptor before the call to SetNamedSecurityInfo.

    Wednesday, January 31, 2007 9:30 PM
  • I've read all that spec, and it looks like it depends on your definition of "main executable", but it also says that tasks requiring privilege should be broken out into a separate executable. So it seems to me that you just need to fire up a separate requiresAdministrator executable to control the services, and the user will get a consent prompt to elevate that process. If it doesn't happen very often it wouldn't be too unfriendly.

    Another way I've seen described to deal with these situations is to have a broker service that your app talks to with an RPC mechanism. This broker service does the privileged actions on behalf of the client.  So you'd need another service that the client talks to wth (say) .NET remoting, and the client tells this service that it wants to start/stop the other service.

    There are some security settings that could help too. I've not looked at this but Service SIDs might help.

    Thursday, February 1, 2007 3:19 PM