Craig Box's journeys, stories and notes...


Querying the status of a Windows service

An interesting puzzle presented itself to me at work yesterday. We have some code called from an ASP.NET application, which queries the status of a service. This works fine when you run the application pool as NetworkService, but if you run it as the IWAM_SERVERNAME user that is created for running IIS processes, it would fail.

I wrote a console application with exactly the same code that the ASP.NET application used, and it worked fine.

Interesting aside: you can find the password for the IWAM_SERVERNAME user by using the Metabase Explorer from the IIS 6 Resource Kit. It's under the Server/LM/W3SVC node as WAMUserPass, and you have to enable "View/Secure Data" to see it. Then, use runas /user:iwam_servername cmd.exe, and enter in the password from the metabase.

Why? Well, surely it must just be some kind of permissions issue, not the Winter Madness.

What can't be done with subinacl isn't worth doing, so I pulled it out and had a look at the service. Here's the important part:

/pace =interactive      ACCESS_ALLOWED_ACE_TYPE-0x0
        SERVICE_QUERY_CONFIG-0x1           SERVICE_QUERY_STATUS-0x4           SERVICE_ENUMERATE_DEPEND-0x8
        SERVICE_INTERROGATE-0x80           READ_CONTROL-0x20000               SERVICE_USER_DEFINED_CONTROL-0x0100

(People finding this useful post via search will want to read the full subinacl output.)

Turns out an interactive user can query a server status, but IIS doesn't run interactively. Assigning permission to the IWAM account is the only way to do this:

subinacl /service Service1 /grant=IIS_WPG=s

Problem solved for the web app.

Always one for complete proof, I tested removing interactive access (subinacl /service Service1 /deny=interactive=s). Result as requested - the console app now throws the same exception the web application does.

But wait...

C:\Program Files\Windows Resource Kits\Tools\>subinacl /service Service1 /revoke=interactiveService1
- OpenService Error : 5 Access is denied.

Oops. Big oops. Nothing I can do now seems to be able to let me fix this, because I've lost access to query the status of the server myself.

Some searching led me to an answer: use the sc.exe utility, which lets you control services from the command line. It also lets you set their security descriptors!

C:\Program Files\Windows Resource Kits\Tools\>sc sdshow Service1 
D:(D;;LC;;;IU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;SU)(A;;CR;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

C:\Program Files\Windows Resource Kits\Tools\>sc sdshow Service2
D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CR;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

C:\Program Files\Windows Resource Kits\Tools\>sc sdset Service1 D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CR;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
[SC] SetServiceObjectSecurity SUCCESS

C:\Program Files\Windows Resource Kits\Tools\>subinacl /service Service1
=========================
+Service Service1
=========================
<snip>

Whew. See how the SDs differ between the two services? Ignore the gobbledy-gook that is SDDL, and just copy an example from another similar service.

I suspect I could have granted access using with sc instead of subinacl, but the IWAM_SERVERNAME account and IIS_WPG group don't have well-known SIDs, so I would have had to find out the SID using another utility anyway.

(Hi Mum. This is what I do all day.)

Tags: ,

6 Responses to “Querying the status of a Windows service”

  1. zonk says:

    On an unrelated note, is it still possible to get Ubuntu stickers off yourself in NZ, or do we need to write to another address?

  2. [...] A while ago I wrote about the permission required to query the status of a Windows service. [...]

  3. [...] O comando SC é meio cavernoso, então vou partir para o SubInAcl, que descobri nessa página do Craig Box. [...]

  4. [...] o conselho do Craig Box e baixei o SubInAcl pra dar permissões no windows service, mas o que mais me ajudou foi uma [...]

  5. Albin Joy says:

    Greetings,

    I had a situation like this.
    I had a service1 which is to check on another service2, is 'Running' or 'Stopped'.
    If Service2 is 'Stopped' start the Service2.

    My code was running correct. I had faced acces deny error when i tried to start the service2.
    All i have to do (other that making the code correct) use a ServiceController,
    ServiceController.Service2.Start();

    And most importantly.Changed the properties of the Service1 to Administrative account.
    Rightclick on the property(in Services.msc panel)..select the Log on option.
    Change it to Local Account.
    You are done.

    Good luck guys.
    I hope this will help some of you.

Leave a Reply