on my website (written in ASP.NET/C#) I want the moderaters to be able to start a certain service. The code I have for this is:
ServiceController svcController = new ServiceController("InvidualFileConversion");
if (svcController != null)
{
try
{
svcController.Stop();
svcController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
svcController.Start();
}
catch (Exception ex)
{
// error
}
}
Now when I run this I get the error "Cannot open InvidualFileConversion service on computer", with the additional message: "Acces is denied".
I know this is a problem with permissions, but how do I give myself the proper permissions? Don't come with the answer where I should write: , cause I have tried it and it didn't work. Also I think that is not really the best way to set this up for the whole website when I just need it for these few lines of code.
EDIT: I've added this in my code and it still doesn't work, I get the same exception at the same place. Now it looks like this:
protected void ConvertLink_OnClick(object sender, EventArgs e)
{
//convert();
try
{
//--need to impersonate with the user having appropriate rights to start the service
Impersonate objImpersonate = new Impersonate(domainName, userName, userPassword);
if (objImpersonate.impersonateValidUser())
{
//--write code to start/stop the window service
startWindowsService();
objImpersonate.undoImpersonation();
}
}
catch (Exception Ex)
{ Response.Write(Ex.Message + Ex.InnerException.Message); }
}
private void startWindowsService()
{
ServiceController svcController = new ServiceController("InvidualFileConversion");
if (svcController != null)
{
try
{
svcController.Stop();
svcController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
svcController.Start();
}
catch (Exception ex)
{
// error
}
}
}
I have a Impersonate class that looks like this:
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Security.Principal;
using System.Runtime.InteropServices;
/// <summary>
/// Summary description for Impersonate
/// </summary>
public class Impersonate
{
#region "Class Members"
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext impersonationContext;
#endregion
#region "Class Properties"
public string domainName { get; set; }
public string userName { get; set; }
public string userPassword { get; set; }
#endregion
public Impersonate()
{
//
// TODO: Add constructor logic here
//
}
public Impersonate(string domainName, string userName, string userPassword)
{
this.domainName = domainName;
this.userName = userName;
this.userPassword = userPassword;
}
#region "Impersonation Code"
[DllImport("advapi32.dll")]
public 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)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
public bool impersonateValidUser()
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(this.userName, this.domainName, this.userPassword, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
public void undoImpersonation()
{
impersonationContext.Undo();
}
#endregion
}
So the validation thing works but doesn't solve my problem.. I guess there is still the problem with the permissions.. What do I do to change this?
EDIT 2: The next steps I took involve this:
- Creating a app pool where the identity is set to a user (which is member of an administrator group).
- Set the service "log on" to the same user.
- After running the web app again, it still fails..
However If I put in the Administrator account as credentials in the code, it works.. (Even though I did not use the Administrator in the App Pool and on the service...)
In other words, I can get what I want with the Administrator account, but not with an account I created myself and has the admin rights. I still want to make this work with a user I made myself as I think it is not so safe to put your Administrator credentials available.
On a sidenote, on the server which I work on I have an account that has administrator privileges but is not the 'Administrator'-account.
EDIT 3: This is getting weird. I seems to work now BUT: - without the Impersonation method (it did not work). - I just did what Rob said. I have my own application pool with a user I defined. The windows service has that user specified as well. (The user received Log On As Service right) - With this, it seems to work. - But if debug through my website I still get acces denied. But if just acces my website through the browser and its ip I can start the service.
To sum it up: - Impersonation method doesn't work. - Just using a self created app pool with the currect user works if the service has the user also specified. But it doesn't work in debug mode (still Acces Denied there).
This post is getting to big and I wonder if any still really reads it.. But maybe still someone can provide me with any details? I'm afraid it will fail again somewhere in the future..
Any comment will be appreciated! Floris