Professional Documents
Culture Documents
How to configure IIS in order to enable the use of Named Kernel Objects in Web
Services.
Introduction
It is well agreed that security is an important issue and that it should be treated
seriously. The need for Security measures grew, in the last years, especially due
to the extensive use of the Internet and as a precaution measure to the malicious
activities of crackers and hackers. After saying that, let's face it, security, is a
nightmare for software developers, and merging security in our projects and
working with secured framework demands enormous amount of time, mainly due
to configuration issues.
The article deals with IIS (Internet Information Server), and specifically with Web
Services. Among other stuff, the IIS is Microsoft's implementation for an HTTP
Server; it is heavily used, in the industry, for Web sites and for Web Services.
These characteristics position the IIS in the front line of malicious attacks,
therefore the IIS is loaded with security layers. The purpose of this article is to
help readers with information regarding IIS security configuration.
The IIS Security mechanism is an enormous topic, suitable for a small book,
therefore I choose to focus on a certain case study of how to configure the IIS in
order to enable the use of Named Kernel Objects in a Web Service. Following are
the main two reasons for using this case study:
Disclaimer
If you are dealing with the IIS or plan to, if you need to port a Web site or web
service to IIS version 6 and to Windows 2003, then this article will be of help to
you. Also, the case study in the article deals with Named Kernel Objects, a
subject that is not documented well enough (in my humble opinion). The reader
would also find useful information about Kernel Objects in the Microsoft operating
systems. I expect the reader to have a basic knowledge about Web Services, IIS,
and C#.
Before drilling down into the case study characteristics, it is important to pave the
way by describing what a Kernel Object is. If you are not familiar with this topic, I
recommend jumping to Appendix A first.
The Named Kernel Object feature does not work in Web Services due to default
security attributes. In Windows XP SP 2, the cause is the lack of user rights in the
ProcessModel attribute, and in Windows 2003 Server, the cause is the lack of
user rights due to the IIS_WPG group and the need to use the \Global prefix in
the name of the Named Kernel Object.
In order to successfully use Named Kernel Objects in Win XP Pro SP 2 with IIS
5.x, you need to change the userName attribute of the ProcessModel XML node in
the Machine.Config file (<Windows folder>\Microsoft.NET\Framework\<
Framework version>\CONFIG):
Although, the \Global prefix is part of the solution, it has noting to do with
Terminal Services. The problem occurs from the Console and when you directly
login to a Windows 2003 Server machine. The Widows 2003 Server uses session
namespace, and therefore always returns a handle in the session context (even
for Named Kernel Objects). In order to successfully use Named Kernel Objects in
the Windows 2003 Server, you need to add the Global\ prefix. This will tell the OS
that the Named Kernel Object should be created in the Global session namespace.
I would like to mention that in Window 2003 Server, the problem is even more
annoying because the API returns a valid handle and the GetLastError returns
success. The API call succeeds, it only does not do what we expect it to do.
We pass this hurdle. Hurry! Don’t relax just yet, we are not finished. The above
solution will work for processes that use Named Kernel Objects with the Global\
prefix and run under the same user. If you use Named Kernel Objects in a Web
Service it will not work. Why? In IIS 6, you define an Object Pool or use the
default. The Object Pool runs under a certain Identity (IWAM or Network System,
by default). If the Web Service and the Windows Forms process, for example, run
under a different user, they will not share a session namespace even if you use
the Global\ prefix. In order to pass through this hurdle, you should add the user
which runs the Windows Forms application to the IIS_WPG group. If it is still not
working, make sure the IIS_WPG group has Bypass Traverse Checking rights.
The screenshot below displays the Groups in a Windows 2003 Server. You need to
associate the user with this group.
The screenshot below displays the association of the user above with an
Application Pool (NamedKOTest):
The screenshot below displays the association of the Web Service with the
Application Pool:
The Implementation
As you will see, the source code is not fancy. It only demonstrates the problem
and the solution. You will find two projects: a painfully simple Web Service, and
an “amazing” Windows Forms application with a few lines. For simplicity, put the
Web Service under the IIS root (c:\inetput\wwwroot), and create a virtual
directory for it. Run the Windows Forms application and start the Wait method.
Browse for the WebService1.asmx and activate the SetEvent method. I am sorry
for making the instruction for deploying the Web Service short, it is simply not in
the article scope and these are simple steps which can be found in many pages
on the web.
Conclusions
The case study of Named Kernel Object use in Web Services has a simple
solution. The journey to find this solution, though, was not so simple. The reason
for that is the lack of documentation both on the Web and in the MSDN. This is
also the reason for writing this article in the first place. The article demonstrates
the use of IIS security configuration in a very narrow case study. I hope my
journey to solve the talk about this issue will pay off for the development
community.
Good to know
For some reason, the \Global prefix is not required in Windows 2003 Server when
using two Windows Forms applications. Nevertheless, I think that it is a good
practice to use this prefix because you can not know where your code might be
running in the future.
Tips
Links
Acknowledgment
I would like to thank my friend Mr. Arye Shapiro MD. for his help regarding
English grammar and for his technical advices.
Appendix A
If you are not familiar with the term Kernel Objects, do not worry, you have
probably worked with them without knowing its name. The following is a short
description about a Kernel Object: A Kernel Object is data structure. Microsoft
uses it a lot in Windows to encapsulate objects like: Event, Mutex, Semaphore,
Thread, Process, File Mapping, and many more. Kernel Objects are created by
calling the Win32 API. In general, a Kernel Object is specific for a process. The
handles returned from the API invocation are properties of the creating process.
An exception to that is the Named Kernel Object.
A Named Kernel Object can be shared between processes. The API for Named
Kernel Object handles a string parameter for name. Opening or creating Named
Kernel Objects return a handle which is linked to a shared Kernel Object which is
handled by the OS. When a process (a process is also a Kernel Object) is
initialized, the OS allocates a kernel object handle table. The following diagram
displays the process after initialization:
The following diagram contains two processes A and B. Each process creates an
unnamed event.
As you can see, there are two event kernel objects for each process, hence there
is no sharing. Both operations return with a handle indexed with 0 simply because
both processes have just initialized.
First of all, it is an important and useful feature. Other than that, it is the simplest
way to create a single instance process (e.g. when you try to run an ICQ process
for the second time, the first instance is displayed). This is done by creating a
named Mutex in the Main method and checking the return code of the
GetLastError API. ERROR_ALREADY_EXISTS indicates that the process is already
running. Another implementation is the use of shared memory between processes
by the File Mapping objects, and for signaling events between processes.
Note: The example shows that the System returns the index 14 as the address. I
am not sure about that. The System might just as well return the 0xAEdad4
address. I am making this assumption because this subject is undocumented and
because it does not interfere with the discussion.
The following diagram contains two processes (A and B). Both create a named
event. Process A does it first as we saw in the previous diagram.
As you can see, the index returned by the API is 2. I deliberately added another
Kernel Object to index 1 (let's say Process B created a thread). I did it to stress
that the index number is not relevant to the Named Kernel Object feature.