none
CurrentPrincipal (+ CoImpersonateClient P/Invoke) issues making DCOM calls to a C# .Net 3.5 Server RRS feed

  • Question

  • Hi,

    I have an old Win32 C++ DCOM Server that I am rewriting to use C# .Net 3.5. The client applications sit on remote XP machines and are also written in C++. These clients must remain unchanged, hence I must implement the interfaces on new .Net objects.

    This has been done, and is working successfully regarding the implementation of the interfaces, and all of the calls are correctly being made from the old clients to the new .Net objects.

    However, I'm having problems obtaining the identity of the calling user from the DCOM Client. In order to try to identify the user who instigated the DCOM call, I have the following code...

    [DllImport("ole32.dll")]static extern int CoImpersonateClient();
    [DllImport("ole32.dll")]static extern int CoRevertToSelf();
    private string CallingUser
    {
    get
    {
    string sCallingUser = null;
    if (CoImpersonateClient() == 0)
    {
    WindowsPrincipal wp = System.Threading.Thread.CurrentPrincipal as WindowsPrincipal;
    if (wp != null)
    {
    WindowsIdentity wi = wp.Identity as WindowsIdentity;
    if (wi != null && !string.IsNullOrEmpty(wi.Name))
    sCallingUser = wi.Name;
    if (CoRevertToSelf() != 0)
    ReportWin32Error("CoRevertToSelf");
    }
    }
    else
    ReportWin32Error("CoImpersonateClient");
    return sCallingUser;
    }
    }

    private static void ReportWin32Error(string sFailingCall)
    {
    Win32Exception ex = new Win32Exception();
    Logger.Write("Call to " + sFailingCall + " FAILED: " + ex.Message);
    }

    When I get the CallingUser property, the value returned the first few times is correct and the correct user name is identified, however, after 3 or 4 different users have successfully made calls (and it varies, so I can't be more specific), further users seem to be identified as users who had made earlier calls.

    What I have noticed is that the first few users have their DCOM calls handled on their own thread (ie all calls from a particular client are handled by a single unique thread), and then subsequent users are being handled by the same threads as the earlier users, and after the call to CoImpersonateClient(), the CurrentPrincipal matches that of the initial user of that thread.

    To Illustrate:
    User Tom makes DCOM calls which are handled by thread 1 (CurrentPrincipal correctly identifies Tom)
    User Dick makes DCOM calls which are handled by thread 2 (CurrentPrincipal correctly identifies Dick)
    User Harry makes DCOM calls which are handled by thread 3 (CurrentPrincipal correctly identifies Harry)
    User Bob makes DCOM calls which are handled by thread 3 (CurrentPrincipal incorrectly identifies him as Harry)

    Is there something that I am doing wrong?
    Are there any caveats or restrictions on using Impersonations in this way?
    Is there a better or different way that I can RELIABLY achieve what I am trying to do?

    All help would be greatly appreciated.

    Regards
    Andrew

    Friday, April 16, 2010 7:48 AM

Answers

  • Hi Aquus,

    Did you implement your handling thread through the thread pool?

    If you did, it's probably caused by thread pool, since the NO. of threads in thread pool is limited, when you need a new thread, a thread will be picked up from thread pool. After you use it, it will go back to thread pool to be suspended. If you didn't use it in a certain time, it will be killed, otherwise it will be resumed to run something you want. So, according to this property of thread pool, maybe you are using it to implement your handling thread. You can use your own thread instead of thread pool. Because, you can control your own NO. of threads.

    Hope this helpful to you and have a nice day!


    Hope this helpful to you! If you have any further quetions, please feel free to let me know.
    Please mark the right answer at right time.
    Bset Regards,
    Tracy
    • Marked as answer by eryang Tuesday, April 27, 2010 3:39 AM
    Monday, April 26, 2010 3:54 AM

All replies

  • Hi Aquus,

    Did you implement your handling thread through the thread pool?

    If you did, it's probably caused by thread pool, since the NO. of threads in thread pool is limited, when you need a new thread, a thread will be picked up from thread pool. After you use it, it will go back to thread pool to be suspended. If you didn't use it in a certain time, it will be killed, otherwise it will be resumed to run something you want. So, according to this property of thread pool, maybe you are using it to implement your handling thread. You can use your own thread instead of thread pool. Because, you can control your own NO. of threads.

    Hope this helpful to you and have a nice day!


    Hope this helpful to you! If you have any further quetions, please feel free to let me know.
    Please mark the right answer at right time.
    Bset Regards,
    Tracy
    • Marked as answer by eryang Tuesday, April 27, 2010 3:39 AM
    Monday, April 26, 2010 3:54 AM
  • Hi Aquus,

    It seems Tracy gave you a right answer, so I marked it.

    However, if you have any further questiones, please feel free to unmark it and we will discuss this issue again.


    Sincerely,
    Eric
    MSDN Subscriber Support in Forum
    If you have any feedback of our support, please contact msdnmg@microsoft.com.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Tuesday, April 27, 2010 3:40 AM