By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,091 Members | 1,917 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,091 IT Pros & Developers. It's quick & easy.

WEB Service access to Windows Service

P: n/a
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";
}
Nov 21 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
I'm guessing it didn't work because setting the folder is not enough to give
the anonymous user access to the Windows Service. Instead of doing this,
consider running your web service as another user rather than the default
anonymous user. Then give the user enough rights to start/stop the Windows
Service. This way, when you call your Web service, the Web service will run
as the new user in IIS, and, assuming it has the proper rights, it should be
able to manipuate the Windows Services. Of course, if you plan on doing
this, you should properly secure your web service.

Eric
--
Eric Cherng
MCP, MCDBA, MCSD
http://echerng.com
"Doug Bailey" <db*****@radiancetech.com> wrote in message
news:f3**************************@posting.google.c om...
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";
}

Nov 21 '05 #2

P: n/a
What do I need to do this? I went to the service's IIS directory and
turned off the anonymous access. I still got the same results when I
ran it.

Do I need to do anything to the service's web.config file. Right now
it is set to the default which uses Windows authentication and all
users have privileges.

Doug

"Eric Cherng" <ericch1@remove_the_dot-hotmai.l.com> wrote in message news:<uv**************@TK2MSFTNGP11.phx.gbl>...
I'm guessing it didn't work because setting the folder is not enough to give
the anonymous user access to the Windows Service. Instead of doing this,
consider running your web service as another user rather than the default
anonymous user. Then give the user enough rights to start/stop the Windows
Service. This way, when you call your Web service, the Web service will run
as the new user in IIS, and, assuming it has the proper rights, it should be
able to manipuate the Windows Services. Of course, if you plan on doing
this, you should properly secure your web service.

Eric
--
Eric Cherng
MCP, MCDBA, MCSD
http://echerng.com
"Doug Bailey" <db*****@radiancetech.com> wrote in message
news:f3**************************@posting.google.c om...
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";
}

Nov 21 '05 #3

P: n/a
Here's how to do it. This uses Windows Authentication so if your client
isn't or doesn't support it then this method will not work.

1. Uncheck anonymous access to your Web service and make sure your Windows
Authentication is checked. If you don't uncheck anonymous, access to the Web
service will use anonymous by default.

2. Add this into your web.config for your Web service (in the <system.web>
tag)
<identity impersonate="true" />

3. Access the Web service test page as a Windows user that has the proper
rights on the machine to start/stop web services.

Attached is my sample code that implements this solution and successfully
starts/stops the "FTP Publishing" service.

Eric
--
Eric Cherng
MCP, MCDBA, MCSD
http://echerng.com
"Doug Bailey" <db*****@radiancetech.com> wrote in message
news:f3*************************@posting.google.co m...
What do I need to do this? I went to the service's IIS directory and
turned off the anonymous access. I still got the same results when I
ran it.

Do I need to do anything to the service's web.config file. Right now
it is set to the default which uses Windows authentication and all
users have privileges.

Doug

"Eric Cherng" <ericch1@remove_the_dot-hotmai.l.com> wrote in message
news:<uv**************@TK2MSFTNGP11.phx.gbl>...
I'm guessing it didn't work because setting the folder is not enough to
give
the anonymous user access to the Windows Service. Instead of doing this,
consider running your web service as another user rather than the default
anonymous user. Then give the user enough rights to start/stop the
Windows
Service. This way, when you call your Web service, the Web service will
run
as the new user in IIS, and, assuming it has the proper rights, it should
be
able to manipuate the Windows Services. Of course, if you plan on doing
this, you should properly secure your web service.

Eric
--
Eric Cherng
MCP, MCDBA, MCSD
http://echerng.com
"Doug Bailey" <db*****@radiancetech.com> wrote in message
news:f3**************************@posting.google.c om...
>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";
> }



Nov 21 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.