How to Start/Stop a Windows Service from an ASP.NET app - Security issues How to Start/Stop a Windows Service from an ASP.NET app - Security issues asp.net asp.net

How to Start/Stop a Windows Service from an ASP.NET app - Security issues


To give IIS permission to start/stop a particular service:

  • Download and install Subinacl.exe. (Be sure to get the latest version! Earlier versions distributed in some resource kits don't work!)
  • Issue a command similar to: subinacl /service {yourServiceName} /grant=IIS_WPG=F

This grants full service control rights for that particular service to the built-in IIS_WPG group. (This works for IIS6 / Win2k3.) YMMV for newer versions of IIS.)


Try adding this to your Web.Config.

<identity impersonate="true"/>


This was a good question that intrigued me as well...

So here is what I did to solve this problem:

  • Step 1: Create a Windows user account on the local machine with minimal rights.
  • Step 2: Give this user rights to start and stop the service via subinacl.exe
  • i.e. subinacl.exe /service WindowsServiceName /GRANT=PCNAME\TestUser=STOE
  • Dowload from : http://www.microsoft.com/en-za/download/details.aspx?id=23510
  • Step 3: Use Impersonation to impersonate the use created in Step 1 to start and stop the Service

    public const int LOGON32_PROVIDER_DEFAULT = 0;WindowsImpersonationContext _impersonationContext;[DllImport("advapi32.dll")]// ReSharper disable once MemberCanBePrivate.Globalpublic static extern int LogonUserA(String lpszUserName,    String lpszDomain,    String lpszPassword,    int dwLogonType,    int dwLogonProvider,    ref IntPtr phToken);[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]// ReSharper disable once MemberCanBePrivate.Globalpublic static extern int DuplicateToken(IntPtr hToken,    int impersonationLevel,    ref IntPtr hNewToken);[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]// ReSharper disable once MemberCanBePrivate.Globalpublic static extern bool RevertToSelf();[DllImport("kernel32.dll", CharSet = CharSet.Auto)]// ReSharper disable once MemberCanBePrivate.Globalpublic static extern bool CloseHandle(IntPtr handle);private bool _impersonate;public bool ImpersonateValidUser(String userName, String domain, String password){    IntPtr token = IntPtr.Zero;    IntPtr tokenDuplicate = IntPtr.Zero;    if (RevertToSelf())    {        if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,            LOGON32_PROVIDER_DEFAULT, ref token) != 0)        {            if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)            {                var tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);                _impersonationContext = tempWindowsIdentity.Impersonate();                if (_impersonationContext != null)                {                    CloseHandle(token);                    CloseHandle(tokenDuplicate);                    _impersonate = true;                    return true;                }            }        }    }    if (token != IntPtr.Zero)        CloseHandle(token);    if (tokenDuplicate != IntPtr.Zero)        CloseHandle(tokenDuplicate);    _impersonate = false;    return false;}#region Implementation of IDisposable#endregion#region Implementation of IDisposableprivate void Dispose(bool dispose){    if (dispose)    {        if (_impersonate)            _impersonationContext.Undo();        _impersonationContext.Dispose();    }}public void Dispose(){    Dispose(true);}#endregionpublic static void StartStopService(bool startService, string serviceName){    using (var impersonateClass = new Impersonation())    {        impersonateClass.ImpersonateValidUser(Settings.Default.LocalUsername, Settings.Default.Domain, Settings.Default.Password);        using (var sc = new ServiceController(serviceName))        {            if (startService)                sc.Start();            else if (sc.CanStop)                sc.Stop();        }    }}