Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. COM
  4. DCOM and ConnectionPoint

DCOM and ConnectionPoint

Scheduled Pinned Locked Moved COM
helpc++sysadminsecurity
9 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    Firoz
    wrote on last edited by
    #1

    Hi, I have an ATL component. My Client is a standard VB application. The component fires events. Events are directly handled by VB Client. This works fine as long as the component is a local server. I want to use this component from a remote machine.. But when I make it a remote server, I get the error, "PERMISSION DENIED" I tried all possible combinations in DcomCnfg Dialog. I specified the permissions (in Security Tab). I tried "Interactive & Launching User" Identities but it gives the same error. But when I specify the Username & password of the client machine, it creates an instance of server on Host machine... ...But it hangs after that.. Can anyone help me out .... Is it that one cannot use Connection points in Dcom ...:confused: Please some body reply to this message.... Firoz.

    R T S 4 Replies Last reply
    0
    • F Firoz

      Hi, I have an ATL component. My Client is a standard VB application. The component fires events. Events are directly handled by VB Client. This works fine as long as the component is a local server. I want to use this component from a remote machine.. But when I make it a remote server, I get the error, "PERMISSION DENIED" I tried all possible combinations in DcomCnfg Dialog. I specified the permissions (in Security Tab). I tried "Interactive & Launching User" Identities but it gives the same error. But when I specify the Username & password of the client machine, it creates an instance of server on Host machine... ...But it hangs after that.. Can anyone help me out .... Is it that one cannot use Connection points in Dcom ...:confused: Please some body reply to this message.... Firoz.

      R Offline
      R Offline
      Rashid Thadha
      wrote on last edited by
      #2

      With Connection Points you have too have the right Security Setting on both machines. Essentially it is a two way duplex communication system Machine A must have right to Machine B and Machine B must have rights to Machine A Check you security settings on both Machines

      1 Reply Last reply
      0
      • F Firoz

        Hi, I have an ATL component. My Client is a standard VB application. The component fires events. Events are directly handled by VB Client. This works fine as long as the component is a local server. I want to use this component from a remote machine.. But when I make it a remote server, I get the error, "PERMISSION DENIED" I tried all possible combinations in DcomCnfg Dialog. I specified the permissions (in Security Tab). I tried "Interactive & Launching User" Identities but it gives the same error. But when I specify the Username & password of the client machine, it creates an instance of server on Host machine... ...But it hangs after that.. Can anyone help me out .... Is it that one cannot use Connection points in Dcom ...:confused: Please some body reply to this message.... Firoz.

        T Offline
        T Offline
        Tim Smith
        wrote on last edited by
        #3

        You can programatically correct this problem. I will try to remember to post the code I use. If you don't hear from me in a day or two, send me an email. Tim Smith Descartes Systems Sciences, Inc.

        1 Reply Last reply
        0
        • F Firoz

          Hi, I have an ATL component. My Client is a standard VB application. The component fires events. Events are directly handled by VB Client. This works fine as long as the component is a local server. I want to use this component from a remote machine.. But when I make it a remote server, I get the error, "PERMISSION DENIED" I tried all possible combinations in DcomCnfg Dialog. I specified the permissions (in Security Tab). I tried "Interactive & Launching User" Identities but it gives the same error. But when I specify the Username & password of the client machine, it creates an instance of server on Host machine... ...But it hangs after that.. Can anyone help me out .... Is it that one cannot use Connection points in Dcom ...:confused: Please some body reply to this message.... Firoz.

          T Offline
          T Offline
          Tim Smith
          wrote on last edited by
          #4

          The first thing that should be done is that COM security should be turned off in the client. Of course, if your client is also acting as a server or is a DLL being loaded by another application, you might not have this option.

          hResult = CoInitializeSecurity (NULL, -1, NULL, NULL,
          	RPC\_C\_AUTHN\_LEVEL\_NONE, RPC\_C\_IMP\_LEVEL\_IDENTIFY,
          	NULL, EOAC\_NONE, NULL);
          

          This needs to be done after you call CoInitialize or CoInitializeEx. Next, you need a routine in your server such as the following.

          //-----------------------------------------------------------------------------
          //
          // @func Remove all security
          //
          // @parm IUnknown * | pUnk | Interface to remove security
          //
          // @rdesc Routine results
          //
          //-----------------------------------------------------------------------------

          inline HRESULT DtRemoveSecurity (IUnknown *pUnk)
          {
          HRESULT hResult;

          //
          // Get the real IUnknown interface
          //
          
          CComPtr <IUnknown> pRealUnk;
          hResult = pUnk ->QueryInterface (IID\_IUnknown, (void \*\*) &pRealUnk);
          if (SUCCEEDED (hResult) && pRealUnk != pUnk)
          {
          	hResult = CoSetProxyBlanket (pRealUnk, RPC\_C\_AUTHN\_NONE,
          		RPC\_C\_AUTHZ\_NONE, 0, RPC\_C\_AUTHN\_LEVEL\_NONE, 
          		RPC\_C\_IMP\_LEVEL\_ANONYMOUS, 0, EOAC\_NONE);
          }
          
          //
          // Set the original unknown
          //
          
          hResult = CoSetProxyBlanket (pUnk, RPC\_C\_AUTHN\_NONE, 
          	RPC\_C\_AUTHZ\_NONE, 0, RPC\_C\_AUTHN\_LEVEL\_NONE, 
          	RPC\_C\_IMP\_LEVEL\_ANONYMOUS, 0, EOAC\_NONE);
          return hResult;
          

          }

          Next thing you will need to do is modify your XXX::Advise method for your connection point. You might have to subclass the ATL routine do to this. Inside the XXX::Advise routine, there is usally a point where the interface is queried for the actual interface needed. The code should be modified.

          	CComPtr <IUnknown> p;
          	HRESULT hResult = pUnkSink ->QueryInterface (\*\_piid, (void \*\*) &p);
          	if (FAILED (hResult))
          	{
          		DtRemoveSecurity (pUnkSink);
          		hResult = pUnkSink ->QueryInterface (\*\_piid, (void \*\*) &p);
          		if (FAILED (hResult))
          			return CONNECT\_E\_CANNOTCONNECT;
          	}
          

          This code test to see if you can query the interface. If it fails then security is removed and then another attempt is made. At this stage it is important that you don't blindly remove security since that causes problems with connections on the local machine. Now, if you are using a GIT based connection point, then after the interface is retrieved from the GIT, you will need to invoke DtRemoveSecurity on the retrieved interface. This can be

          R 1 Reply Last reply
          0
          • T Tim Smith

            The first thing that should be done is that COM security should be turned off in the client. Of course, if your client is also acting as a server or is a DLL being loaded by another application, you might not have this option.

            hResult = CoInitializeSecurity (NULL, -1, NULL, NULL,
            	RPC\_C\_AUTHN\_LEVEL\_NONE, RPC\_C\_IMP\_LEVEL\_IDENTIFY,
            	NULL, EOAC\_NONE, NULL);
            

            This needs to be done after you call CoInitialize or CoInitializeEx. Next, you need a routine in your server such as the following.

            //-----------------------------------------------------------------------------
            //
            // @func Remove all security
            //
            // @parm IUnknown * | pUnk | Interface to remove security
            //
            // @rdesc Routine results
            //
            //-----------------------------------------------------------------------------

            inline HRESULT DtRemoveSecurity (IUnknown *pUnk)
            {
            HRESULT hResult;

            //
            // Get the real IUnknown interface
            //
            
            CComPtr <IUnknown> pRealUnk;
            hResult = pUnk ->QueryInterface (IID\_IUnknown, (void \*\*) &pRealUnk);
            if (SUCCEEDED (hResult) && pRealUnk != pUnk)
            {
            	hResult = CoSetProxyBlanket (pRealUnk, RPC\_C\_AUTHN\_NONE,
            		RPC\_C\_AUTHZ\_NONE, 0, RPC\_C\_AUTHN\_LEVEL\_NONE, 
            		RPC\_C\_IMP\_LEVEL\_ANONYMOUS, 0, EOAC\_NONE);
            }
            
            //
            // Set the original unknown
            //
            
            hResult = CoSetProxyBlanket (pUnk, RPC\_C\_AUTHN\_NONE, 
            	RPC\_C\_AUTHZ\_NONE, 0, RPC\_C\_AUTHN\_LEVEL\_NONE, 
            	RPC\_C\_IMP\_LEVEL\_ANONYMOUS, 0, EOAC\_NONE);
            return hResult;
            

            }

            Next thing you will need to do is modify your XXX::Advise method for your connection point. You might have to subclass the ATL routine do to this. Inside the XXX::Advise routine, there is usally a point where the interface is queried for the actual interface needed. The code should be modified.

            	CComPtr <IUnknown> p;
            	HRESULT hResult = pUnkSink ->QueryInterface (\*\_piid, (void \*\*) &p);
            	if (FAILED (hResult))
            	{
            		DtRemoveSecurity (pUnkSink);
            		hResult = pUnkSink ->QueryInterface (\*\_piid, (void \*\*) &p);
            		if (FAILED (hResult))
            			return CONNECT\_E\_CANNOTCONNECT;
            	}
            

            This code test to see if you can query the interface. If it fails then security is removed and then another attempt is made. At this stage it is important that you don't blindly remove security since that causes problems with connections on the local machine. Now, if you are using a GIT based connection point, then after the interface is retrieved from the GIT, you will need to invoke DtRemoveSecurity on the retrieved interface. This can be

            R Offline
            R Offline
            Rashid Thadha
            wrote on last edited by
            #5

            Excellent solution (about removing the security from the client), very clever, fits in with what Jeff Prosise says about connection points. extract from Jeff Prosise article

            One of the errors that newbies often experience when they first
            begin tinkering with DCOM occurs when they fail to give a remote
            server process permission to perform callbacks to a client.
            Suppose a client on machine A launches a COM server on machine B
            and receives an interface pointer in return. Then that client
            passes an interface pointer of its own to the server so the
            server can perform callbacks.

            What's wrong with this picture? Nothing, except for the fact
            that callbacks will only be permitted if the server process is
            granted access permission to the client process. If the server
            process is assigned the identity Mister Server, then Mister
            Server must be granted access permission to the client process.
            One way to grant that access permission is to have the client
            process call CoInitializeSecurity. Another way is to include
            Mister Server (or Everyone) in the client machine's
            DefaultAccessPermission ACL.

            What makes this error especially difficult to diagnose is that
            if connection points are involved, the failure typically doesn't
            occur when the server attempts its first callback; it occurs
            when the client passes its interface pointer to the server using
            IConnectionPoint::Advise. Most implementations of Advise,
            including ATL's, call QueryInterface on the client. But if the
            server process lacks access permissions in the client process,
            QueryInterface will fail. When Advise sees QueryInterface fail,
            Advise will fail, too.

            The moral: If you're using connection points to facilitate
            callbacks from remote servers and IConnectionPoint::Advise
            returns E_ACCESSDENIED or E_OUTOFMEMORY, check the access
            permissions on the client. Chances are the security principal
            whose identity the server process has been assigned does not
            have permission to call into the client process.

            Read the full security article at http://www.codeguru.com/activex/COMSecurity1.html and http://www.codeguru.com/activex/COMSecurity2.html

            T 1 Reply Last reply
            0
            • R Rashid Thadha

              Excellent solution (about removing the security from the client), very clever, fits in with what Jeff Prosise says about connection points. extract from Jeff Prosise article

              One of the errors that newbies often experience when they first
              begin tinkering with DCOM occurs when they fail to give a remote
              server process permission to perform callbacks to a client.
              Suppose a client on machine A launches a COM server on machine B
              and receives an interface pointer in return. Then that client
              passes an interface pointer of its own to the server so the
              server can perform callbacks.

              What's wrong with this picture? Nothing, except for the fact
              that callbacks will only be permitted if the server process is
              granted access permission to the client process. If the server
              process is assigned the identity Mister Server, then Mister
              Server must be granted access permission to the client process.
              One way to grant that access permission is to have the client
              process call CoInitializeSecurity. Another way is to include
              Mister Server (or Everyone) in the client machine's
              DefaultAccessPermission ACL.

              What makes this error especially difficult to diagnose is that
              if connection points are involved, the failure typically doesn't
              occur when the server attempts its first callback; it occurs
              when the client passes its interface pointer to the server using
              IConnectionPoint::Advise. Most implementations of Advise,
              including ATL's, call QueryInterface on the client. But if the
              server process lacks access permissions in the client process,
              QueryInterface will fail. When Advise sees QueryInterface fail,
              Advise will fail, too.

              The moral: If you're using connection points to facilitate
              callbacks from remote servers and IConnectionPoint::Advise
              returns E_ACCESSDENIED or E_OUTOFMEMORY, check the access
              permissions on the client. Chances are the security principal
              whose identity the server process has been assigned does not
              have permission to call into the client process.

              Read the full security article at http://www.codeguru.com/activex/COMSecurity1.html and http://www.codeguru.com/activex/COMSecurity2.html

              T Offline
              T Offline
              Tim Smith
              wrote on last edited by
              #6

              Yup, I got my info from Essential COM. Tim Smith Descartes Systems Sciences, Inc.

              F 1 Reply Last reply
              0
              • T Tim Smith

                Yup, I got my info from Essential COM. Tim Smith Descartes Systems Sciences, Inc.

                F Offline
                F Offline
                Firoz
                wrote on last edited by
                #7

                Thats great Tim, Thanx a lot...:-O But how can I do this with a VB client... May be, I will have to use one more component at the client side which will talk to the remote component and simply forward the events fired by the remote component to the VB Client. (But then, as you said, I cannot turn off the COM security) What can I do in this situation ?? Anyway, I will try out this... Any other suggesion about handling the remote events directly by the VB Client...?? coz...My client is in VB and I cannot change that... Thanks... Firoz

                1 Reply Last reply
                0
                • F Firoz

                  Hi, I have an ATL component. My Client is a standard VB application. The component fires events. Events are directly handled by VB Client. This works fine as long as the component is a local server. I want to use this component from a remote machine.. But when I make it a remote server, I get the error, "PERMISSION DENIED" I tried all possible combinations in DcomCnfg Dialog. I specified the permissions (in Security Tab). I tried "Interactive & Launching User" Identities but it gives the same error. But when I specify the Username & password of the client machine, it creates an instance of server on Host machine... ...But it hangs after that.. Can anyone help me out .... Is it that one cannot use Connection points in Dcom ...:confused: Please some body reply to this message.... Firoz.

                  S Offline
                  S Offline
                  Shadi Al Kahwaji
                  wrote on last edited by
                  #8

                  Hi, DCOM is a Client calling a component on another computer called Server. When we talk about Events, the roles should be changed, the client will be the server and the server will be the client(Security wise). Goto this article, it might help you in this problem. http://www.codeproject.com/useritems/dcomcnfg.asp Don't forget that while configuring the client and the server, you have to give the server the required security privileges to call back the client. Regards, ShadiK. Shadi Al-Kahwaji

                  F 1 Reply Last reply
                  0
                  • S Shadi Al Kahwaji

                    Hi, DCOM is a Client calling a component on another computer called Server. When we talk about Events, the roles should be changed, the client will be the server and the server will be the client(Security wise). Goto this article, it might help you in this problem. http://www.codeproject.com/useritems/dcomcnfg.asp Don't forget that while configuring the client and the server, you have to give the server the required security privileges to call back the client. Regards, ShadiK. Shadi Al-Kahwaji

                    F Offline
                    F Offline
                    Firoz
                    wrote on last edited by
                    #9

                    Thanks Shadi... Giving the Server the required Security Rights made it work... :-O

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups