SERVICE_DACL

Use SERVICE_DACL to verify the discretionary access control list (DACL) permissions on a Windows service. The check compares the service's access control entries (ACEs) against the entries you define inline, without requiring a separate <service_acl> block. This makes it a self-contained replacement for the older SERVICE_PERMISSIONS check type.

Note: This check requires access to the Service Control Manager on the target Windows system and sufficient permissions to read the service security descriptor.

Usage

<custom_item>

type: SERVICE_DACL

description: ["description"]

service: ["service name"]

dacl: ["principal"] || ["right"]

dacl: ["principal"] || ["right"]

(optional) dacl: ["principal"] || ["right"] || ["scope"]

(optional) check_type: [CHECK_EQUAL|CHECK_SUBSET|CHECK_SUBSET_USER|CHECK_SUPERSET]

(optional) acl_option: [CAN_BE_NULL]

</custom_item>

The service field is the short service name as registered with the Service Control Manager (for example Spooler, W32Time, Dnscache), not the display name.

Each dacl line defines one access control entry (ACE). The fields are separated by the || operator, in the order:

"principal" || "right" [|| "scope"]

The following describes each segment of a dacl line:

  • principal — The user or group name, or a raw SID string (for example Administrators, SYSTEM, Interactive, Authenticated Users). Principal names are compared case-insensitively.
    • To assign multiple granular rights to one principal, use multiple dacl lines for that principal. The rights are OR'd together.
  • right — A single service permission. Supported values: full control, read, write, start, stop and pause, query template, change template, query status, enumerate dependents, start, stop, pause and continue, interrogate, user-defined control, delete, read permissions, change permissions, take ownership.
  • scope — Optional third segment indicating which objects the ACE applies to. Supported values: this object only (default), this object and child objects. Unlike FILE_DACL and REGISTRY_DACL, SERVICE_DACL has no inheritance segment; service ACEs are always treated as non-inherited.

Additional field notes:

  • Use service to specify the short service name (for example, Spooler), not the display name (not "Print Spooler").
  • check_type — Determines how the policy ACL is compared against the system ACL. Defaults to CHECK_EQUAL when omitted.
  • CHECK_EQUAL — Requires an exact match.
  • CHECK_SUBSET — Requires the policy ACEs to be a subset of the system ACEs.
  • CHECK_SUBSET_USER — Same as CHECK_SUBSET, but ignores principals present on the system that are not listed in the policy.
  • CHECK_SUPERSET — Requires the system rights to be greater than or equal to the policy rights.
  • acl_option — Set to CAN_BE_NULL to pass the check if the service does not exist.

Examples

Verify that administrators and SYSTEM have full control of the Spooler service:

<custom_item>

type: SERVICE_DACL

description: "Spooler - administrators and SYSTEM have full control"

service: "Spooler"

dacl: "Administrators" || "full control"

dacl: "SYSTEM" || "full control"

check_type: CHECK_SUBSET_USER

</custom_item>

Specify multiple granular rights for a single principal:

<custom_item>

type: SERVICE_DACL

description: "W32Time - interactive users limited access"

service: "W32Time"

dacl: "Interactive" || "query template"

dacl: "Interactive" || "query status"

dacl: "Interactive" || "enumerate dependents"

dacl: "Interactive" || "interrogate"

dacl: "Interactive" || "user-defined control"

dacl: "Interactive" || "read permissions"

check_type: CHECK_SUBSET_USER

</custom_item>

Pass when an optional service may not be installed:

<custom_item>

type: SERVICE_DACL

description: "Optional service - check if installed"

service: "SomeOptionalService"

dacl: "Administrators" || "full control"

acl_option: CAN_BE_NULL

check_type: CHECK_SUBSET

</custom_item>

Comparison with the legacy SERVICE_PERMISSIONS style

The older SERVICE_PERMISSIONS check requires a separate <service_acl> block referenced by value_data:

<service_acl:"ACL3">

  <user:"Administrators">

    acl_inheritance : "not inherited"

    acl_apply       : "this object only"

    acl_allow       : 'full control'

  </user>

  <user:"SYSTEM">

    acl_inheritance : "not inherited"

    acl_apply       : "this object only"

    acl_allow       : 'full control'

  </user>

</service_acl>

 

<custom_item>

type: SERVICE_PERMISSIONS

description: "Spooler service permissions"

value_type: SERVICE_ACL

value_data: "ACL3"

service: "Spooler"

check_type: CHECK_SUBSET

</custom_item>

The equivalent self-contained SERVICE_DACL check:

<custom_item>

type: SERVICE_DACL

description: "Spooler service permissions"

service: "Spooler"

dacl: "Administrators" || "full control"

dacl: "SYSTEM" || "full control"

check_type: CHECK_SUBSET

</custom_item>