WindowsIdentity

WindowsIdentity is IDisposable.

Recently I went on a quest to dispose of IDisposable objects wherever I could find them, since many types are IDisposable but people are not aware of this fact. (Suggestion for VS2010, shade types which are IDisposable a different color in the IDE.)

WindowsIdentity.GetCurrent() returns an instance which you should dispose, otherwise you temporarily leak a user handle. (Its a safehandle so its not a huge deal).
Infact, most times you use WindowsIdentity it is good to dispose of the item. Except for one case.

If you call Impersonate() on a WindowsIdentity instance, disposing it will cause hard to diagnose crashes.

It took me a while to work out why, so I thought I would write this up, maybe it’ll save someone else out there the trouble once.

Reflecting through windows identity related code, tokens get duplicated and new WindowsIdentity instances get created all over the place, so it would seem that you were safe to dispose.
However, when you call Impersonate, the WindowsIdentity instance, and its internal safe handle, get stuffed into the current security context, without being copied or duplicated. I don’t know whether that security context disposes the instance later (looks like it doesn’t), but it effectively takes ownership of it, so you can’t.

If you do dispose of it, and you start a timer or queue a work item before the impersonation is undone, when that timer or work item is executed, the .net framework attempts to set up the security context by impersonating again, but the safe handle is already disposed.

As a bonus, you can disable security support in the .Net runtime, in which case the newly corrected code temporarily leaks handles without the runtime being responsible for the leak.

5 thoughts on “WindowsIdentity”

  1. Hi, I’m just starting to teach myself how to really program. I’ve had a 3 year break after taking some required C/C++ courses in college. I was wondering if you could send me any of your code for LoopDeLoop.exe because I can’t get over all the shapes and options you have. I’m really curious as to how it’s done and I’m thinking it may teach me a thing or two. Let me know if this is possible, even a dumbed down version would be appreciated. Thanks!

  2. While I don’t give away source code to my apps, feel free to use ‘Reflector’ to see what it does.
    Fair warning that its not all pretty – there is a significant difference between when I write code for myself, and when I write it for others.

  3. Hello,

    In your move around the WindowsIdentity Impersonate code, did you find any reason why the Dispose() method wouldn’t actually dispose of the object? I’m getting a warning in a profiler stating that the WindowsIdentity was GC’d but wasn’t disposed of even though I called the Dispose() method.

    1. I don’t have anything useful for you sorry. Without knowing how the profiler determines the scenario I can’t be sure, but it sounds like a false positive, or a miss identification of the location of allocation of the WindowsIdentity object which is not being disposed. (Maybe it isn’t even in your code.)

  4. Hey Tilps,

    I actually just found the issue and since I posted the problem, I figured I’d post the solution.

    The WindowsIdentity.GetCurrent() returns a WindowsIdentity. The code example on MSDN was calling WindowsIdentity.GetCurrent().Name and posting it to the console. This call to GetCurrent() still creates an object in memory and since we don’t have a reference we can’t properly dispose of it.

    To remedy this, every time the example used GetCurrent().Name, I stored the WindowsIdentity reference, used its Name property, then called Dispose() on it. If you re-use the same reference for each of the three calls, then you must call Dispose() in between each re-assignment or a reference will be left in memory.

    Sorry about the posts but I hate to post a question and not post an answer for future blog readers!

Leave a Reply

Your email address will not be published. Required fields are marked *