Permissions required for a local user to query services

I'm trying to write an application, that is running as a local user on the server, and needs access to enumerate services, and potentially even control them (start/stop).

Is being a part of the administrators group the only way this user would be able to get access to this functionality (being used via the ServiceController class)? If easier, I'd be ok with even just being able to enumerate the list of services (the interactive starting/stopping isn't a show-stopper). Would adding the user to the power user's group work?

Thanks!

edit: http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx#access_rights_for_the_service_control_manager


Solution 1:

The Power Users group is never the answer. It's an old legacy thing. Best to just consider it non-existent.

If you want to set permissions on individual Windows services in a granular way, you can, but it's nowhere near as easy/intuitive as setting permissions on a file

To view the current permissions of a Windows service:

C:\Users\Ryan>sc sdshow netlogon

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCR
RC;;;IU)(A;;CCLCSWLOCRRC;;;SU)

To set the permissions on a single Windows service, for example, so that a non-admin user can start and stop a particular service:

sc sdset netlogon "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;S-1-5-21-2103278432-2794320136-1883075150-1000)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"
[SC] SetServiceObjectSecurity SUCCESS

That looks awful, doesn't it? That goo is called SDDL - Security Descriptor Definition Language.

This article is a pretty good primer on how to interpret SDDL and do what you're trying to do.

You can also use Security Templates and Group Policies to accomplish the same thing:

Security Template

Solution 2:

Another friendly option for doing the same thing is the subinacl command line tool included in the Windows 2003 Resource Kit. It is a wonderful little bag of tricks.

Here is the syntax for setting user permissions on services:

SUBINACL /SERVICE \\MachineName\ServiceName /GRANT=[DomainName\]UserName[=Access]

These are the Access-options available:

F : Full Control
R : Generic Read
W : Generic Write
X : Generic eXecute
L : Read controL
Q : Query Service Configuration
S : Query Service Status
E : Enumerate Dependent Services
C : Service Change Configuration
T : Start Service
O : Stop Service
P : Pause/Continue Service
I : Interrogate Service 
U : Service User-Defined Control Commands

So to give the members of the group DOMAIN\GroupName permission to start and stop the service 'ServiceName' one would:

subinacl /service ServiceName /GRANT=DOMAIN\GroupName=TO

To view permissions set on the service 'ServiceName' (before and after running the above) one would:

subinacl.exe /service /verbose=1 ServiceName

Here is an official HOWTO for setting service permissions using subinacl: http://support.microsoft.com/kb/288129

And here is the subinacl download link: http://www.microsoft.com/en-us/download/details.aspx?id=23510

Solution 3:

To enumerate services, your process needs the SC_MANAGER_ENUMERATE_SERVICE right, in the old days every authenticated user had this right, but since Vista this is no longer the case.

Interactive users have it, that's why a normal user can do a net start or Get-Service

You can change the permissions on the Service Control Manager to allow your process to enumerate services. You also need to change permissions on any service you want to access.

I just wrote a blog post about how to do this, it includes a PowerShell script to do this for all services on the local machine.