{"id":9533,"date":"2011-09-28T07:00:00","date_gmt":"2011-09-28T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2011\/09\/28\/does-this-operation-work-when-impersonating-the-default-answer-is-no\/"},"modified":"2021-01-04T10:53:59","modified_gmt":"2021-01-04T18:53:59","slug":"20110928-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20110928-00\/?p=9533","title":{"rendered":"Does this operation work when impersonating? The default answer is NO"},"content":{"rendered":"<p>I&#8217;ll often see a customer ask for assistance with a scenario like this: &#8220;We&#8217;re having trouble doing X. We&#8217;re doing X1, X2, and X3, but it looks like we&#8217;re getting the wrong answer back.&#8221;<\/p>\n<p>The next step in the conversation goes something like &#8220;There must be something else going on, because X1, X2 and X3 is the correct way of doing X. To demonstrate, I&#8217;ve written the following sample program that illustrates doing X by the X1, X2, X3 technique. When I run it, I get the correct answer. What do you get when you run it?&#8221;<\/p>\n<p>&#8220;When we run your program we get the correct answer, but it doesn&#8217;t work when we do it from our program.&#8221; And then, as if by afterthought, &#8220;Could the problem be that we&#8217;re impersonating?&#8221;<\/p>\n<p>Ohhhhhh, you&#8217;re <i>impersonating<\/i>. Thanks for not mentioning that.<\/p>\n<p>By default, nothing works when impersonating. Impersonation requires end-to-end awareness. A function might create a worker thread\u2014the worker thread runs with the identity of the process. A function might use a function like <code>Queue\u00adUsere\u00adWork\u00adItem<\/code>\u2014by default, the work item runs with the identity of the process. (You have to pass <code>WT_<wbr \/>TRANSFER_<wbr \/>IMPERSONATION<\/code> if you want the work item to respect impersonation.) A function might send a message to another window\u2014that window will do its work under its own security token, not the token of the sender. A function might invoke a method on a remote COM object\u2014that object will run under its own security token, not the token of the invoker. (COM requires you to call <code>Co\u00adSet\u00adProxy\u00adBlanket<\/code> to enable impersonation transfer during marshaling, and the server needs to call <code>CoImpersonateClient<\/code>. For some reason, this is called <a href=\"http:\/\/msdn.microsoft.com\/library\/ms683778.aspx\">cloaking<\/a>.) The registry keys <code>HKEY_CURRENT_USER<\/code> and <code>HKEY_CLASSES_ROOT<\/code> don&#8217;t work when you&#8217;re impersonating. (You have to <a href=\"http:\/\/msdn.microsoft.com\/library\/ms724836.aspx\"> use <code>RegOpenCurrentUser<\/code> or <code>RegOpenUserClassesRoot<\/code><\/a>.) Functions like <code>SHGetKnownFolderPath<\/code> have a token parameter which is used when impersonating; if you pass <code>NULL<\/code>, then it assumes you aren&#8217;t impersonating.<\/p>\n<p>The requirements go beyond just code that runs during the execution of the function in question. If you have a function which caches information across calls, the cache needs to be made impersonation-aware so that a value calculated when called while impersonating user\u00a0X isn&#8217;t mistakenly used while impersonating user\u00a0Y.<\/p>\n<p>In order for impersonation to work, every function all the way down the chain needs to be impersonation-safe. Sure, you might be careful to call <code>QueueUserWorkItem<\/code> with the <code>WT_TRANSFER_IMPERSONATION<\/code> flag, and your work item is careful to call <code>SetProxyBlanket<\/code> on its COM objects, and your COM server is careful to call <code>CoImpersonateClient<\/code> when servicing the call, but if your COM server then calls a helper object which calls <code>SHGetKnownFolderPath<\/code> and passes <code>NULL<\/code> for the impersonation token, then all your careful work has been for naught.<\/p>\n<p>This is another special case of <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20100414-00\/?p=14333\"> <i>When you create an object with constraints, you have to make sure everybody who uses the object understands those constraints<\/i><\/a>.<\/p>\n<p>The Programming Golden Rule can be applied here as well: <i>When you write your own code, do you do this?<\/i> Since most people who write code do not think about impersonation (indeed, the operating system even encourages not-impersonation-safe coding when it provides conveniences like <code>HKEY_CURRENT_USER<\/code>) the default answer to &#8220;Does this work when I&#8217;m impersonating&#8221; is &#8220;No.&#8221;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Impersonation requires end-to-end support.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-9533","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Impersonation requires end-to-end support.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/9533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=9533"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/9533\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=9533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=9533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=9533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}