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

Help: E_ACCESSDENIED from CoCreateInstance

225 views
Skip to first unread message

Eric Scholer

unread,
Sep 18, 2002, 4:40:49 PM9/18/02
to
I have an ATL service that creates a singleton COM component. DCOM Clients
then access the service using CoCreateInstanceEx. Everything worked fine
until I needed to implement security to limit access to certain users. I
modified the ATL generated call to CoInitializeSecurity to limit access to
users in a given group as follows:

CSecurityDescriptor sd;
sd.InitializeFromThreadToken();
hr = sd.Allow( _T("SYSTEM"), COM_RIGHTS_EXECUTE );
hr = sd.Allow( _T("MyUsersGroup"), COM_RIGHTS_EXECUTE ); // only allow
users in local group 'MyUsersGroup' to access component
hr = CoInitializeSecurity(sd, -1, NULL, NULL,RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);

This works in that I can only create the component if I am logged in as a
user in the group 'MyUsersGroup'; if I am logged in as a user that is not in
this group, I get E_ACCESSDENIED as expected.

The problem is that I want to be able to access the component when I am
logged in as a user that is not in the group by explicitly providing
authentication information for a known user that is in the group. This
should be straightforward - just provide the name, domain and password of an
authorized user in the COSERVERINFO->COAUTHINFO->COAUTHIDENTITY structure in
the call to CoCreateInstanceEx:

// myuser is a member of MyUsersGroup and should be able to access the
component
// both myuser and MyUsersGroup are part of local domain mycomputer
COAUTHIDENTITY aid= { L"myuser", 6, L"mycomputer", 10, L"password", 8,
SEC_WINNT_AUTH_IDENTITY_UNICODE };
COAUTHINFO ai = { RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, &aid, EOAC_NONE };
COSERVERINFO si = { NULL, L"localhost", &ai, NULL };
MULTI_QI qi = { &IID_IUnknown, NULL, S_OK };
hr = ::CoCreateInstanceEx( CLSID_MyService, NULL, CLSCTX_REMOTE_SERVER,
&si, 1, &qi );

Problem is this code fails with hr = E_ACCESSDENIED. I've tried many many
combinations of parameter values and DCOMCNFG settings but always get
E_ACCESSDENIED. Are there any steps I am missing? Is there anyway of
getting more detailed information on why E_ACCESSDENIED is returned? The
service is already running and has created the component when I execute the
client code. I am running Windows XP professional, build environment is
VC6.

Alexander Nickolov

unread,
Sep 18, 2002, 6:30:36 PM9/18/02
to
Is that a local or a domain account? You specified a local account
in your COAUTHIDENTITY structure.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnic...@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

"Eric Scholer" <esch...@lenel.com> wrote in message news:et19GO1XCHA.4264@tkmsftngp08...

Salvador Girbau

unread,
Sep 18, 2002, 6:27:58 PM9/18/02
to
(Lifting and insecure finger, in order to say:)
I believe CoCreateInstanceEx security settings affect the "connect"
authentication level only. Yet the CreateService call is requiring "packet"
level, and negotiation will bring, at least, a value as high as "packet".
Is your client calling CoInitializeSecurity, in order to provide
a user authentification default? (Which is not probably what you want to do.)
Did you try RPC_C_AUTHN_LEVEL_CONNECT in CreateService ?

What I do NOT know for certain, is why the ATL wizard uses the packet level
when it writes code for the service, in the first place; or if this is some
sort of a requirement.

Salvador Girbau

unread,
Sep 18, 2002, 6:42:19 PM9/18/02
to
Oops. Errata fixes:
substitute /CreateService/ for /CoInitializeSecurity at the server/.
Time to go to sleep, I guess.

Eric Scholer

unread,
Sep 19, 2002, 9:36:24 AM9/19/02
to
> Is your client calling CoInitializeSecurity, in order to provide a user
authentification default?
My client does not call CoInitializeSecurity (although I have tried this and
it didn't help). I understand that CoInitializeSecurity can only be called
once per process. My client is an in-process COM component so it probably
wouldn't be able to call CoInitializeSecurity early enough for it to work in
practice.

> Did you try RPC_C_AUTHN_LEVEL_CONNECT in CreateService ?

Yes. Still got E_ACCESSDENIED.

> Is that a local or a domain account? You specified a local account in your
COAUTHIDENTITY structure.

I have created a local group "MyUsersGroup" and a local account "myuser"
which is a member of that group.
In the server's CoInitializeSecurity call I create a security descriptor
that allows access to "MyUsersGroup".
I created another local account "eric" that is not part of the MyUsersGroup.
I am trying to get the client to be
able to connect to the service (i.e. create an instance of the singleton
component that the service exposes) when
logged into the "eric" account by explicitly authenticating as "myuser".
Both the client and the server are
running on the same machine. The server is already running and has created
the singleton component instance
before the client starts.

?? In general, when developing DCOM code, is there any way of determining
where and why access fails??

"Salvador Girbau" <sgi...@numen.es> wrote in message
news:3d88fb0f...@msnews.microsoft.com...


> (Lifting and insecure finger, in order to say:)
> I believe CoCreateInstanceEx security settings affect the "connect"
> authentication level only. Yet the CreateService call is requiring
"packet"
> level, and negotiation will bring, at least, a value as high as "packet".
> Is your client calling CoInitializeSecurity, in order to provide
> a user authentification default? (Which is not probably what you want to
do.)
> Did you try RPC_C_AUTHN_LEVEL_CONNECT in CreateService ?

"Alexander Nickolov" <agnic...@mvps.org> wrote in message
news:#iC8#J2XCHA.3736@tkmsftngp08...

Alexander Nickolov

unread,
Sep 19, 2002, 2:29:00 PM9/19/02
to
I believe (but I'm not sure) the problem is your local access. The
COM SCM simply ignores your COAUTHIDENTITY structure for
local calls and therefore the call arrives with the credentials of
the original caller. I have some vague memory of a post from a
Microsoft employee in the microsoft.public.win32.programmer.ole
newsgroup about the rationale behind (quite some time ago...).
The solution would be to do LogonUser/ImersonateLoggedOnUser
before you call CoCreateInsatnceEx without COSERVERINFO. Again,
I'm not 100% sure this solution will work - I haven't tested it myself.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnic...@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

"Eric Scholer" <esch...@lenel.com> wrote in message news:u6C7nF#XCHA.1664@tkmsftngp09...

Eric Scholer

unread,
Sep 20, 2002, 11:49:24 AM9/20/02
to
I think we might be on the right track here - I tried a couple of new
scenarios to test this:

When connecting from the same computer, I tried using
LoginUser/ImpersonateLoggedOnUser. Both these calls succeed, however, the
CoCreateInstanceEx still fails with E_ACCESSDENIED (COSERVERINFO.pAuthInfo
is NULL).

I tried connecting from a different computer. In this case, COM seems to
use the COAUTHINDENTITY structure and CoCreateInstanceEx successfully
creates the remote object. However, any calls on the returned interface
pointer return E_ACCESSDENIED. Arrgghh!! Also, QueryInterface also fails
with E_ACCESSDENIED unless the IID was in the CoCreateInstanceEx MULTI_QI
structure.


As another interesting test, I created an ASP page that creates an instance
of my object using VB script's CreateObject() method. The ASP page runs on
the same computer as the COM service. If I try to display the ASP page, I
get an ASP VBScript runtime error [Permission denied: 'CreateObject'] as
expected. However, if I provide authentication information in the url, e.g.
http://myuser:password@myserver/mypage.asp, then the page works! This works
whether I try to display the page from a local or remote computer. So,
there is a way to create the object as a specific user. If only I knew how
IIS does the impersonation...

"Alexander Nickolov" <agnic...@mvps.org> wrote in message

news:OT74nnAYCHA.1676@tkmsftngp11...

Eric Scholer

unread,
Sep 20, 2002, 5:37:27 PM9/20/02
to
I was able to get everything to work when the client is on a remote
computer.

When the client is on the same computer as the service, I still get
E_ACCESSDENIED. Even if I LogonUser/ImpersonateUser to assume the identity
of a user that should be able to access the component. I can see that
LogonUser/ImpersonateUser work because subsequent calls to GetUserName
return the name of the impersonated user, however, the call to
CoCreateInstance apparently doesn't use the impersonated user because it
fails with E_ACCESSDENIED. Any ideas?


"Alexander Nickolov" <agnic...@mvps.org> wrote in message

news:OT74nnAYCHA.1676@tkmsftngp11...

0 new messages