DEV Community

Warren
Warren

Posted on

How to grant users rights to manage services

Chances are if you've been looking at how to grant a Windows user account or group the permissions needed to start/stop or otherwise control a service then you've seen MS's article on doing so. Trouble is it seems to be ancient, certainly the tools like Subinacl.exe are so old that most of the search engine links for it end up directing you to the wayback machine to get hold of it. No thanks! So I ended up in a rabbit hole of posts but have figured it out.

SIDs, DACLs, SACLs, oh my!

If you've never heard of any of these before, don't worry, you're not the only one.
Security IDentifiers (SID) are used to identify anything you can assign permissions to, e.g. users, groups, etc. MS refers to these as "trustees".
Discretionary Access Control Lists (DACL) are used to control grant/deny permissions to a trustee for accessing the related securable (in our case service).
System Access Control Lists (SACL) are used for controlling what access attempts get logged. We will not be changing these, but the process is essentially the same as as changing DACLs.

Cat from Red Dwarf saying "So what is it?"

A SID is an ID that describes authority information for a trustee. More details can be found by reading Security identifier architecture. They look something like S-1-5-32-544 or S-1-5-27-8351948176-95729385651-85920185638-195.
An ACL is a string containing groups of permissions and the group they apply to.

Cat from Red Dwarf saying "So what is it?"

That's funny if you've seen the show, and if you haven't you should Red Dwarf is awesome

tldr; We're going to get a SID for the account/group we want to give permissions to, a DACL for the service we want to control, and we're going to edit the DACL to include permissions for our SID.

Getting the Service DACL

To get the ACLs for the service we're going to use the sc.exe sdshow command. Run sc.exe sdshow "Wibble" where "Wibble" is the name of your service.
You should get a completely unintelligible string like

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
Enter fullscreen mode Exit fullscreen mode

Interpreting the ACL

You see the D: that means that section is the start of the DACL. Later on there's a S:, and yes, that's the start of the SACL.
Let's focus on the DACL

Interpreting the DACL

(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)
Enter fullscreen mode Exit fullscreen mode

Believe it or not that actually has meaning, and isn't the result of some sort of binary conversion gone wrong. It's written using something called Security Descriptor Definition Language (SDDL) which uses something else called Access Control Entry (ACE) strings.
This is possibly the least accessible, most obscure thing I've come across in >30 years of using Windows, but mostly because the documentation is all over the place. Once you have a key, it actually becomes fairly easy to decode, so lets do that.

Each of the sections in the brackets are granting permissions to a different group. These are the ACE strings mentioned above. Lets take the first one

A;;CCLCSWRPWPDTLOCRRC;;;SY
Enter fullscreen mode Exit fullscreen mode

The first character will either be A for "Allow" or D for "Deny". In this case these are the allowed permissions.
The last two characters are telling us which group that section applied to. See the "SDDL users and groups" section on this summary of SDDL for a key. So SY tells us these are the permissions for the "Local System".
The middle bit are the sets of permissions. For this you'd need the "SDDL access rights" section of the above article, but the codes are all related to registry key permissions, and still need translating into what that will do to the service. For that there's 👇 which I found in this old knowledgebase article.

Pair Right or permission
CC QueryConf
DC ChangeConf
LC QueryStat
SW EnumDeps
RP Start
WP Stop
DT Pause
LO Interrogate
CR UserDefined
GA GenericAll
GX GenericExecute
GW GenericWrite
GR GenericRead
SD Del
RC RCtl
WD WDac
WO WOwn

So CCLCSWRPWPDTLOCRRC means the group will have the QueryConf, QueryStat, EnumDeps, Start, Stop, Pause, Interrogate, UserDefined, and RCtl permissions. I don't have a clue what half of those are if I'm honest, because I saw what I wanted, namely Start, Stop, Pause, Interrogate.

So an ACE to grant permissions to start/stop/pause and interrogate the service would look like

A;;RPWPDTLO;;;???
Enter fullscreen mode Exit fullscreen mode

Ah, not quite there yet, we still don't know the SID for the account we want to use. That's what will take the place of the ??? in our ACE.

Getting a SID

We can use the PowerShell Get-WmiObject commandlet to get the SID for the group we want to apply the permissions to.

(Get-WmiObject win32_group | Where-Object { $_.Name -eq "NameOfUserGroupThatNeedsPermissionForOurService"} ).SID
Enter fullscreen mode Exit fullscreen mode

That should give you the SID to go in our ACE string.

Putting it together

Combining our ACE string with the SID now gives us

A;;RPWPDTLO;;;S-1-5-27-8351948176-95729385651-85920185638-195
Enter fullscreen mode Exit fullscreen mode

Take the ACL and add that inside a set of brackets in the D: part.

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPDTLO;;;S-1-5-27-8351948176-95729385651-85920185638-195)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
Enter fullscreen mode Exit fullscreen mode

And now for the final step (well done for getting this far, it's been a long one). Assign the permissions using sc.exe sdset.

sc.exe sdset "Wibble" "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPDTLO;;;S-1-5-27-8351948176-95729385651-85920185638-195)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"
Enter fullscreen mode Exit fullscreen mode

Simple as that 🫤

Top comments (0)