Friday, July 16, 2010

How to Delegate Services control in Windows

Microsoft offers a very helpful document here and here detailing how to use subinacl to give control over a service to a user. Unfortunately, they’ve not updated that article in quite some time, and it’s now out of date: beginning with Windows Server 2003 SP1, authenticated users no longer can enumerate services.
While that’s a good thing, it renders the solution presented by Microsoft only partially complete.
So we’ll correct that, going through all the steps that are necessary to give an (otherwise) unprivileged user permissions to control any given services through the services control panel. This will work on Windows Server through v2008 R2.

Assemble the Tools

We’ll use three command-line tools, two of which will need to be installed on the destination server. The first is sc, which is installed by default, happily.
The second is subinacl. It’s possible to use sc instead of subinacl, but the learning curve for subinacl is much less steep. Subinacl can be downloaded from Microsoft here.
You’ll also need access to dsquery; this is installed on Windows 7 and Server 2008 if you’ve installed the Active Directory Domain Controller Tools feature (see below for a screen shot on how to install that feature in Windows Server 2008).
image

Grant Permissions to Enumerate Services

So with Windows Server 2003 SP1, authenticated users no longer can enumerate services by default. Probably a good choice, but that means we need to grant that permission before our delegate can run the services control panel and connect it to our server.


Determine the SID of the user you’re wanting to grant access to

Because SC uses SIDs, rather than usernames, we’ve got to get the SID of the user we want to deal with. We’ll use dsquery to do this, thus:
dsquery * -filter "&(objectcategory=user)(samaccountname=<username>)" -attr objectsid
where <username> is the login name for the user we want. The above will return the SID, something like this:

C:\>dsquery * -filter "&(objectcategory=user)(samaccountname=testuser)" -attr objectsid
objectsid S-1-5-21-214A909598-1293495619-13Z157935-75714
Note the SID; we’ll use it below.

Grant access to run the Services Control Panel

We’ll use sc to do this. First, run sc to get the current SDDL for the services control manager:
sc sdshow scmanager
You’ll get something like this:
D:(A;;CC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)
This is SDDL, and if you’re interested, you can start reading with Microsoft’s KB914392 for more information.
For our purposes, though, it’s enough to do this:
  • Copy the results of the above command (sc sdshow scmanager) to a text editor.
  • Copy the section of the SDDL that ends in IU (interactive users) to just before the S: in the SDDL line.
  • In the copied text, replace ‘IU’ with the SID of the user to whom you are granting access, such that your SDDL looks something like that below:

D:(A;;CC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)(A;;CCLCRPRC;;;S-1-5-21-214A909598-1293495619-13Z157935-75714)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)

Now we’ll run the set command:
sc sdset scmanager "D:(A;;CC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)(A;;CCLCRPRC;;;S-1-5-21-214A909598-1293495619-13Z157935-75714)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)"

Note that we’re replacing the permissions on scmanager; this isn’t additive. That’s why we needed to copy the existing permissions. So if you’re needing to grant access to another person, you’ll need to duplicate the section with the SID and add another.

Grant access to the Service

Now that our user can enumerate services, we’ll grant access to control a service. In our example here, we’ll use the Print Spooler service, since that’s a harmless one, but you can do this with any service(s) you require.
This is where we’ll use subinacl, and the format is simple:
subinacl /verbose /service "service name" /grant=DOMAIN\username=F
Note that the service name is the “short” format. You can query that using sc:

sc getkeyname “service name from services control panel”

thus:
C:\>sc getkeyname "print spooler" [SC] GetServiceKeyName SUCCESS Name = Spooler

So in our case, we’ll do this:
subinacl /verbose /service “Spooler” /grant=TEST\testuser=F

‘F’, by the way, is full control.

The double quotes aren’t necessary, except in cases where the service name has spaces.

Our user now can run the services control panel on a remote workstation and connect to the server to control the print spooler service.

Note that even though the user can see other services, there’s isn’t any permission to control them.

4 comments:

  1. Although I've used this technique in the past, it becomes very tedious to maintain when dealing with hundreds or thousands of servers. I'm developing a web based tool to centralize the delegation of service management, including specific rights like start, stop, kill (including wildcard service name matches). It's called System Frontier. I wonder how many admins out there are having to delegate rights like this across a large number of servers and for how many users? A lot of folks end up just giving too many people local administrator access.

    ReplyDelete
  2. Jay, you're right: a tool to streamline this process would be great; I'm surprised, too, that there hasn't been a greater outcry for having something like a MMC plugin that would allow you to manage this.

    Keep us updated on System Frontier; would love to see it in action!

    ReplyDelete
  3. System Frontier is now available. With it, you can delegate windows service management as well as rights to manage processes, scheduled task and any script or command-line too without giving end users rights directly on your servers. Check out screenshots and more features or request a free 30 day trial at http://systemfrontier.com

    ReplyDelete

Thanks for leaving a comment!