Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CreateEvent fails with ERROR_INVALID_OWNER

170 views
Skip to first unread message

GBergeron

unread,
Sep 20, 2005, 8:43:59 PM9/20/05
to
We're calling the Win32, CreateEvent, and it's failing with
ERROR_INVALID_OWNER = "this security ID may not be assigned as the
owner of this object". Here's the setup.

We have a .NET class library (called .CAL) that calls into an unmanaged
C-callable DLL (OMDAPI.DLL). The class library is hosted in a Web
page. The Web page is running in IIS with anonymous access turned off.


The web.config contains these entries:
<authentication mode="Windows" />
<identity impersonate="true" userName="" password="" />
Therefore, we're trying to have the Web page impersonate the client
browser's user.

When OMDAPI.DLL connects to the ASPNET_WP process, during the
DLL_PROCESS_ATTACH, it creates a static CSecurityDescriptor (from ATL).
It calls InitializeFromThreadToken() on that CSecurityDescriptor. The
DACL is null for this CSecurityDescriptor.

The first user connects to the page, which calls into the class library
which calls into the DLL. The DLL calls CreateEvent with a unique name
and a SECURITY_ATTRIBUTES structure. The event name is generated from
the username and some other data. Therefore, for each user, we're
generating a different event name. The SECURITY_ATTRIBUTES structure
is filled in with the CSecurityDesriptor (m_pSD) that was created
during DLL_PROCESS_ATTACH. The first user's call to CreateEvent
succeeds. I'm not 100% sure, but I believe this is the first time this
security descriptor is actually used.

The second user that logs in fails with ERROR_INVALID_OWNER. The
second user is coming in from a different machine since we're using
impersonation, it must be from a different user. It's been seen,
sometimes on Windows Server 2003, that the second user gets in OK, but
the third user fails. So basically, it fails after at most 3 users.
The primary test platform has been Windows 2000.

Now, OMDAPI.DLL has been around for a long time (6-7 years) and works
fine in stand-alone, multi-threaded Windows applications. It has only
started failing now that we're hosting this in a Web page.

I've tried giving the ASPNET user account these privileges but they
don't work:
- administrator privileges
- "act as part of the operating system"

I haven't verified this, but it seems likely that each user is coming
in on a different thread. The first user gets in and grabs ownership
of that security descriptor. Then when the second user comes in on the
second thread, it fails because it's already owned by the first
thread/user. Does that sound reasonable?

Some other things:
- it's not in our class library because someone else wrote their own
class library and called into OMDAPI.DLL and they get the same problem.

- We're not trying to recreate the event name because it's different
for each user.

Any help as to why we're getting this ERROR_INVALID_OWNER would be
greatly appreciated.

Thanks in advance.

Richard Ward

unread,
Sep 23, 2005, 3:02:08 AM9/23/05
to
invalid_owner means that you have specified an owner in the
security descriptor owner SID that is not present in your thread
or process token (and marked SE_GROUP_OWNER) at the time
that you create the object. Likely, you are not impersonating anymore,
or you are impersonating now, but the security descriptor was created
when you weren't.

"GBergeron" <spoonie...@yahoo.com> wrote in message
news:1127263439.1...@g43g2000cwa.googlegroups.com...

GBergeron

unread,
Sep 26, 2005, 4:44:43 PM9/26/05
to

Richard,

Your advice is right on the money. The security descriptor was created
at DLL_PROCESS_ATTACH - when we are not impersonating. Then when a user
logs on, we do the impersonation.

First question: why does it work for the first user then fail for the
second user? Shouldn't it fail for the first user as well?
Second question: based on your original response, how do I go about
fixing this problem?
1) Just pass NULL for the SECURITY_ATTRIBUTES in the call to
CreateEvent
2) Use InitializeFromProcessToken (which calls OpenProcessToken)
instead of InitializeFromThreadToken
3) After we do the impersonation, set the owner SID to current
(impersonated) user
4) something else?

#1 is obviously the easiest but least secure
#2 is easy but I'm not sure the implication of using the process token
over the thread token
#3 is tricky because currently we have a single static security
descriptor for the whole DLL. This sort of leads me to believe a thread
token is not the way to go since we may have many different threads in
this process and they may be impersonating different users. Maybe we
should go with #2.

Richard Ward

unread,
Sep 27, 2005, 2:37:25 AM9/27/05
to

"GBergeron" <spoonie...@yahoo.com> wrote in message
news:1127767483....@g43g2000cwa.googlegroups.com...

>
> Your advice is right on the money. The security descriptor was created
> at DLL_PROCESS_ATTACH - when we are not impersonating. Then when a user
> logs on, we do the impersonation.
>
> First question: why does it work for the first user then fail for the
> second user? Shouldn't it fail for the first user as well?
> Second question: based on your original response, how do I go about
> fixing this problem?
> 1) Just pass NULL for the SECURITY_ATTRIBUTES in the call to
> CreateEvent
> 2) Use InitializeFromProcessToken (which calls OpenProcessToken)
> instead of InitializeFromThreadToken
> 3) After we do the impersonation, set the owner SID to current
> (impersonated) user
> 4) something else?
>
> #1 is obviously the easiest but least secure
> #2 is easy but I'm not sure the implication of using the process token
> over the thread token
> #3 is tricky because currently we have a single static security
> descriptor for the whole DLL. This sort of leads me to believe a thread
> token is not the way to go since we may have many different threads in
> this process and they may be impersonating different users. Maybe we
> should go with #2.
>

In general, you put security descriptors on objects where you are worried
that different principals will be trying to access those objects, outside of
your
control. I don't know enough about what you're trying to do to make a
recommendation, nor (I confess) do I know anything about ATL's
interpretation
of security descriptors. I don't know what InitializeFromThreadToken is
supposed
to do.

If it were me, I would probably create a security descriptor through SDDL
and have
it say something like: <your process, be it system or IUSR_Xxx or
whatever>:full,
Creator-owner:F, and pass that into CreateEvent(). I would do this only
when I
can guarantee that I am impersonating. The resulting object would have a
DACL that
granted access to the creator and to whatever your host is running as.


0 new messages