How to Grant Domain Users Permission to Start/Stop Multiple Tomcat Services Across Servers


10 views

The standard Windows service permission methods (like sc.exe sdset or subinacl.exe) often fail for Tomcat services because they use Java Service Wrapper implementations that create unique security contexts. Here's the technical reality:

# Standard approach that WON'T work:
sc.exe sdset Tomcat9 "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPDTLO;;;S-1-5-32-547)"

For managing 100+ Tomcat instances across 15 servers, we need a hierarchical approach:

  1. Create a domain security group (e.g., DOMAIN\Tomcat_Operators)
  2. Implement either:
    • Wrapper-Specific: Modify each Tomcat service's wrapper.conf
    • Windows-Level: Scripted permission assignment

Add this to each wrapper.conf:

# Grant start/stop to domain group
wrapper.ntservice.account=DOMAIN\Tomcat_Operators
wrapper.ntservice.password.interactive=false
wrapper.ntservice.starttype=auto
wrapper.ntservice.interactive=false

Create a PowerShell deployment script:

$services = Get-CimInstance -ClassName Win32_Service -Filter "Name LIKE 'Tomcat%'"
$groupSID = (New-Object System.Security.Principal.NTAccount("DOMAIN\Tomcat_Operators")).Translate([System.Security.Principal.SecurityIdentifier])

foreach ($service in $services) {
    $sd = Get-Service -Name $service.Name | Get-ServiceSecurity
    $sd.AddAccessRule((New-Object System.ServiceProcess.ServiceAccessRule(
        $groupSID,
        [System.ServiceProcess.ServiceAccessRights]::GenericAll,
        [System.Security.AccessControl.AccessControlType]::Allow
    )))
    $sd | Set-ServiceSecurity
}

When using tools like Ant sshexec with jsch, ensure:

  • The remote session has proper token impersonation rights
  • The domain user has both service rights and remote access rights

Sample Ant target:

<target name="restart-tomcats">
    <sshexec host="${server}" username="${user}" password="${pass}"
             command="net stop ${service.name} && net start ${service.name}"
             trust="true" failonerror="true"/>
</target>

For enterprise environments, consider:

# Group Policy Preferences (GPP) XML snippet
<NTServices clsid="{...}">
  <Service name="Tomcat*" action="R" userContext="0" 
           desc="Tomcat Services">
    <SecurityDescriptor DACL="D:(A;;RPWPDTLO;;;S-1-5-21-...-1234)"/>
  </Service>
</NTServices>

When dealing with Tomcat services installed via Windows Service Wrapper (like procrun), standard Windows service permission methods often fail. The primary issue stems from how Tomcat registers services with unique SIDs, making group-based permission management particularly tricky.

For enterprise environments with multiple Tomcat instances across servers, we need a scalable solution. Here's the technical approach:

# PowerShell script to grant service control permissions
$serviceName = "Tomcat9"
$domainGroup = "DOMAIN\TomcatAdmins"

# Get service SID
$service = Get-WmiObject -Class Win32_Service -Filter "Name='$serviceName'"
$serviceSid = (New-Object System.Security.Principal.NTAccount($service.StartName)).Translate([System.Security.Principal.SecurityIdentifier]).Value

# Build SDDL string
$newSddl = "D:(A;;CCLCSWRPWPDTLOCRRC;;;$serviceSid)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)(A;;RPWPDTRC;;;$domainGroup)"

For managing 100+ services across 15 machines, consider this automation strategy:

# Batch script using psexec for multiple servers
@echo off
set SERVERS=server1 server2 server3
set SERVICE_NAMES=TomcatA TomcatB TomcatC
set DOMAIN_GROUP=DOMAIN\TomcatAdmins

for %%s in (%SERVERS%) do (
    for %%t in (%SERVICE_NAMES%) do (
        psexec \\%%s sc sdset %%t "D:(A;;CCLCSWRPWPDTLOCRRC;;;NT AUTHORITY\NETWORK SERVICE)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)(A;;RPWPDTRC;;;%DOMAIN_GROUP%)"
    )
)

For environments using Ant sshexec (jsch), ensure proper command syntax:

<sshexec host="${server}" 
         username="${user}" 
         password="${password}" 
         command="net stop ${service.name} && net start ${service.name}"
         trust="true"/>

Critical note: The executing account needs both Windows-level permissions AND SSH access rights.

For large-scale deployments, consider creating a management service that:

  • Runs under a domain account with necessary privileges
  • Exposes a controlled API for service management
  • Logs all control actions for audit purposes
// Java example using Apache Commons Daemon
ServiceController controller = new ServiceController();
controller.setAccount("DOMAIN\\svc_tomcatmgmt");
controller.setPassword("securePass123!");
controller.install("Tomcat_Cluster1");