I am trying to control a Windows Service via a Web Service interface.
(I am developing in .NET2003) I am using the ServiceController object
which allows me to read the state of the services with no problems.
However, I am not able to start or stop the service unless I go
through the process of impersonating an administrative user. (See
MSDN KB 306158)
Since it appears to be a privilege issue, I set the folders in IIS
holding the Web Service files to Anonymous Access with the privileges
of the administrative user that I was able to impersonate. This did
not work.
Does anybody have any ideas as to how I need to set the security of
the Web service such that I can get rid of the impersonation code in
my application?
Thanks
Doug
WORKS:
String __gc* streamAccessClass::turnStreamOn()
{
ServiceController * streamCtl = new ServiceController();
streamCtl->ServiceName = "newserviceWinService";
if(streamCtl->get_Status() == ServiceControllerStatus::Stopped
|| streamCtl->get_Status() == ServiceControllerStatus::Paused)
{
cImpersonation * user = new cImpersonation();
try
{
if(user->impersonateValidUser(S"IISTEST", S"BaileyD", S"IISTEST"))
{
streamCtl->Start();
streamCtl->WaitForStatus (ServiceControllerStatus::Running);
user->undoImpersonation();
return S"Streamer is On";
}
else
{
return S"Could not log on";
}
}
catch (Exception * startErr)
{
user->undoImpersonation();
return startErr->get_Message();
}
}
return S"Streamer failed due to improper state";
}
bool cImpersonation::impersonateValidUser(String * userName, String *
domain, String * password)
{
WindowsIdentity * tempWindowsIdentity;
IntPtr token = IntPtr(0);
IntPtr tokenDuplicate = IntPtr(0);
if(RevertToSelf())
{
if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, token) != 0)
{
if(DuplicateToken(token, 2, tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity->Impersonate();
if (impersonationContext != 0)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if(token!= IntPtr::Zero)
CloseHandle(token);
if(tokenDuplicate!=IntPtr::Zero)
CloseHandle(tokenDuplicate);
return false;
}
void cImpersonation::undoImpersonation()
{
if (impersonationContext != 0)
impersonationContext->Undo();
}
DOES NOT WORK:
String __gc* streamAccessClass::turnStreamOn()
{
ServiceController * streamCtl = new ServiceController();
streamCtl->ServiceName = "newserviceWinService";
if(streamCtl->get_Status() == ServiceControllerStatus::Stopped
|| streamCtl->get_Status() ==ServiceControllerStatus::Paused)
{
try
{
streamCtl->Start();
streamCtl->WaitForStatus (ServiceControllerStatus::Running);
return S"Streamer is On";
}
catch (Exception * startErr)
{
return startErr->get_Message();
}
}
return S"Streamer failed due to improper state";
}