Flylib.com

Books Software

 
 
 

Recipe7.13.Granting the Permission to Manage One or More Services


Recipe 7.13. Granting the Permission to Manage One or More Services

Problem

You want to grant a user the right to manage (stop and start) a particular service.

Solution

Using a graphical user interface

  1. Open the Group Policy Object Editor.

  2. Edit the Group Policy object that applies to the computer running the service you want to set security on.

  3. In the right pane, expand Computer Configuration Windows Settings System Services .

  4. In the left pane, double-click the service you want to configure.

  5. Check the box beside Define this policy setting .

  6. Select the service startup type.

  7. Click the Edit Security button.

  8. Use the ACL Editor to choose the target security principal and select the permission to apply.

  9. Click OK to close the ACL Editor.

  10. Click OK to close the setting properties page.

Using a command-line interface:

The following command grants full control of a service for a user:

> subinacl /service \


<ServerName>


\


<ServiceName>


/grant=


<User>



The following example grants full control of the Messenger service on server fs01 to the AMER\rallen user:

> subinacl /service \fs01\Messenger /grant=AMER\rallen

Use this command to view the users who have been granted access to manage a particular service:

> subinacl /verbose=1 /service \


<ServerName>


\


<ServiceName>



Here is an example:

> subinacl /verbose=1 /service \fs-rtp01\Messenger

To revoke access to a service, use this command:

> subinacl /service \


<ServerName>


\


<ServiceName>


/revoke=


<UserName>



This next command grants the AMER\rallen user control over all services on the server fs01 and saves the output to out.txt :

> for /f "tokens=2,*" %s in ( '"psservice.exe  findstr SERVICE_NAME"' ) do subinacl
/verbose=1 /service \fs01\%s /grant=AMER\rallen >> out.txt

Discussion

The access control list (ACL) for a service is stored in the Registry, under the service's Security keye.g., HKLM\System\CurrentControlSet\Services\ <ServiceName> \Security . If you misconfigure the permissions on a service or just want to start over, delete the service's Security key.

Be sure to download the latest version of subinacl from http://download.microsoft.com/. Older versions work in unexpected ways. Another alternative you can also use is the setacl command, which is very similar in functionality to subinacl . setacl is available under the GNU Public License from the following web site: http://setacl. sourceforge .net/.


See Also

For more on service permissions, visit http://www.microsoft.com/technet/prodtechnol/windowsserver2003/proddocs/entserver/sys_srv_permissions.asp.


Recipe 7.14. Script: Robust Service Restart

A service can be dependent on other services and have other services dependent on it. This is a nice feature because you can configure that in order for ServiceA to run, ServiceB needs to already be running. However, this makes things more complicated when it comes to stopping and starting services. If you want start ServiceA, you also need to make sure ServiceB is running.

When it comes to programmatically restarting services, you could just call the StopService and StartService methods on a service. And since a lot of services don't have any dependencies, this will generally work. But if you happen to try restarting a service that has a dependency, the restart will not be successful. The solution to this is to write a bit of code that can handle restarting services, regardless of dependencies. Here is the code:

' This code restarts a service by first stopping all
' dependent services before stopping the target service.
' Then the target service is started and then all dependent 
' services are started.
   
Option Explicit
   
' ------ SCRIPT CONFIGURATION ------
Dim strComputer : strComputer = "."        ' e.g., fs-rtp01
Dim strSvcName  : strSvcName  = "


<ServiceName>


"  ' e.g., dnscache
' ------ END CONFIGURATION ---------
Dim objWMI : set objWMI = GetObject("winmgmts:\" & strComputer & _
                                    "\root\cimv2")
Dim objService: set objService = objWMI.Get("Win32_Service.Name='" & _
                                            strSvcName & "'")
   
WScript.Echo "Restarting " & objService.Name & "..."
RecursiveServiceStop  objService
RecursiveServiceStart objService
WScript.Echo "Successfully restarted service"
   
Function RecursiveServiceStop ( objSvc ) 
   
   Dim colServices : set colServices = objWMI.ExecQuery("Associators of " _
                 & "{Win32_Service.Name='" & objSvc.Name & "'} Where " _
                 & "AssocClass=Win32_DependentService Role=Antecedent" )
   Dim objS
   for each objS in colServices
      RecursiveServiceStop objS
   next
   
   Dim intRC : intRC = objSvc.StopService
   WScript.Sleep 5000  ' Give the service 5 seconds to stop
   if intRC > 0 then
      WScript.Echo " Error stopping service: " & objSvc.Name
      WScript.Quit
   else 
      WScript.Echo " Successfully stopped service: " & objSvc.Name
   end if
End Function
   
Function RecursiveServiceStart ( objSvc )
   
   Dim intRC : intRC = objSvc.StartService
   if intRC > 0 then
      WScript.Echo " Error starting service: " & objSvc.Name
      WScript.Quit
   else
      WScript.Echo " Successfully started service: " & objSvc.Name
   end if
   
   Dim colServices : set colServices = objWMI.ExecQuery("Associators of " _
                 & "{Win32_Service.Name='" & objSvc.Name & "'} Where " _
                 & "AssocClass=Win32_DependentService Role=Antecedent" )
   Dim objS
   for each objS in colServices
      RecursiveServiceStart objS
   next
   
End Function

In order to restart a service, you have to stop all services that are dependent on that service and then stop the service itself. Then to start the service, you have to start the service followed by all dependent services. And that is exactly what this code does. It makes use of a couple of recursive functions that walk through all of the dependent services.