{"id":202,"date":"2007-12-07T05:48:21","date_gmt":"2007-12-06T17:48:21","guid":{"rendered":"http:\/\/craig.dubculture.co.nz\/blog\/2007\/12\/07\/querying-the-status-of-a-windows-service\/"},"modified":"2007-12-24T13:37:38","modified_gmt":"2007-12-24T01:37:38","slug":"querying-the-status-of-a-windows-service","status":"publish","type":"post","link":"http:\/\/craig.dubculture.co.nz\/blog\/2007\/12\/07\/querying-the-status-of-a-windows-service\/","title":{"rendered":"Querying the status of a Windows service"},"content":{"rendered":"<p>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.<\/p>\n<p>I wrote <a href=\"http:\/\/craig.dubculture.co.nz\/blog\/wp-content\/uploads\/2007\/12\/check-servicescs.txt\" title=\"C# app to check service status\">a console application <\/a>with exactly the same code that the ASP.NET application used, and it worked fine.<\/p>\n<p><i>Interesting aside: you can find the password for the IWAM_SERVERNAME user by using the Metabase Explorer from the <a href=\"http:\/\/www.microsoft.com\/downloads\/details.aspx?FamilyID=56FC92EE-A71A-4C73-B628-ADE629C89499&amp;displaylang=en\">IIS 6 Resource Kit<\/a>. 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. <\/i><\/p>\n<p>Why?  Well, surely it must just be some kind of permissions issue, not the Winter Madness.<\/p>\n<p>What can't be done with <a href=\"http:\/\/craig.dubculture.co.nz\/blog\/2006\/06\/30\/windows-utilities-you-didnt-know-about-subinaclexe\/\">subinacl<\/a> isn't worth doing, so I pulled it out and had a look at the service.  Here's the important part:<\/p>\n<pre>\/pace =interactive      ACCESS_ALLOWED_ACE_TYPE-0x0\r\n        SERVICE_QUERY_CONFIG-0x1           SERVICE_QUERY_STATUS-0x4           SERVICE_ENUMERATE_DEPEND-0x8\r\n        SERVICE_INTERROGATE-0x80           READ_CONTROL-0x20000               SERVICE_USER_DEFINED_CONTROL-0x0100<\/pre>\n<p>(People finding this useful post via search will want to read the full <a href=\"http:\/\/craig.dubculture.co.nz\/blog\/wp-content\/uploads\/2007\/12\/service1.txt\" title=\"subinacl output\">subinacl output<\/a>.)<\/p>\n<p>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:<\/p>\n<pre>subinacl \/service Service1 \/grant=IIS_WPG=s<\/pre>\n<p>Problem solved for the web app.<\/p>\n<p>Always one for complete proof, I tested removing interactive access (<tt>subinacl \/service Service1 \/deny=interactive=s<\/tt>). Result as requested - the console app now throws the same exception the web application does.<\/p>\n<p>But wait...<\/p>\n<pre>C:\\Program Files\\Windows Resource Kits\\Tools\\&gt;subinacl \/service Service1 \/revoke=interactiveService1\r\n- OpenService Error : 5 Access is denied.<\/pre>\n<p>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.<\/p>\n<p>Some searching led me to an answer: use the <a href=\"http:\/\/www.microsoft.com\/resources\/documentation\/windows\/xp\/all\/proddocs\/en-us\/sc.mspx?mfr=true\">sc.exe utility<\/a>, which lets you control services from the command line.  It also lets you set their security descriptors!<\/p>\n<pre>\r\nC:\\Program Files\\Windows Resource Kits\\Tools\\&gt;<b>sc sdshow Service1<\/b> \r\nD:(D;;LC;;;IU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;SU)(A;;CR;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)\r\n\r\nC:\\Program Files\\Windows Resource Kits\\Tools\\&gt;<b>sc sdshow Service2<\/b>\r\nD:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CR;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)\r\n\r\nC:\\Program Files\\Windows Resource Kits\\Tools\\&gt;<b>sc sdset Service1<\/b> D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CR;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)\r\n[SC] SetServiceObjectSecurity SUCCESS\r\n\r\nC:\\Program Files\\Windows Resource Kits\\Tools\\&gt;<b>subinacl \/service Service1<\/b>\r\n=========================\r\n+Service Service1\r\n=========================\r\n&lt;snip&gt;<\/pre>\n<p>Whew.  See how the SDs differ between the two services?  Ignore the gobbledy-gook that is <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa379567.aspx\">SDDL<\/a>, and just copy an example from another similar service.<\/p>\n<p>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.<\/p>\n<p>(Hi Mum.  This is what I do all day.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[66,68],"tags":[27,4],"_links":{"self":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/posts\/202"}],"collection":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=202"}],"version-history":[{"count":0,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/posts\/202\/revisions"}],"wp:attachment":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=202"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=202"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=202"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}