469,602 Members | 1,912 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,602 developers. It's quick & easy.

WEB Service access to Windows Service

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
3 3394
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
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
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.

Similar topics

11 posts views Thread by Michael Riggio | last post: by
3 posts views Thread by mailme.faisal | last post: by
9 posts views Thread by SP | last post: by
3 posts views Thread by Matt Lowrance | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.