Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is exception from impersonated code not caught?

My C# code uses impersonation by calling Win32 functions via P/Invoke

internal class Win32Native
{
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern int ImpersonateLoggedOnUser(IntPtr token);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern int RevertToSelf();
}

try {
    var token = obtainTokenFromLogonUser();
    Win32Native.ImpersonateLoggedOnUser( token );
    throw new Exception(); // this is for simulation
    Win32Native.RevertToSelf()
} catch( Exception e ) {
    LogException( e );
    throw;
}

also I have AppDomain.CurrentDomain.UnhandledException handler installed that also logs all unhandled exception.

I'm sure that the code that logs exceptions works fine both with and without impersonation.

Now the problem is that in the above code it looks like catch is not entered and UnhandledException is also not called. The only trace of the exception is an entry in the Event Viewer.

If I add a finally like this:

try {
    var token = obtainTokenFromLogonUser();
    Win32Native.ImpersonateLoggedOnUser( token );
    try {
       throw new Exception(); // this is for simulation
    } finally {
        Win32Native.RevertToSelf()
    }
} catch( Exception e ) {
    LogException( e );
    throw;
}

then the exception is logged okay both from catch and from UnhandledException handler.

What's happening? Does the thread being impersonated prevent usual exception handling?

like image 686
sharptooth Avatar asked Oct 05 '22 17:10

sharptooth


1 Answers

Without seeing the code of the LogException, I can't be sure, but it could be that whatever you are doing in there is doing so in the context of the impersonated / loggedon user and that that user does not have user rights to be doing whatever it is you are doing e.g. writing to a file etc and that the code then crashes at that point. The fact that your code works only after you have "Reverted to Self" seems to bear this out.

So what I'm trying to say it, chances are your exception is actually being caught by the catch, but that the LogException is failing due to it trying to do work in context of an incorrect user.

To test this out, inside your LogException, try force your current context to "Self" before attempting any logging and see whether the 1st snippet now starts working.

like image 149
bob the builder Avatar answered Oct 10 '22 11:10

bob the builder